蓝桥杯在线测试的题目。不定时不断更新中,没按顺序做。
题目地址:http://lx.lanqiao.org/index.page
上一次的因为太长,保存好慢,决定在开一篇。
上一篇:蓝桥杯在线测试的题解(一)http://blog.csdn.net/murmured/article/details/18908567
算法训练- 安慰奶牛
Farmer John变得非常懒,他不想再继续维护供奶牛之间供通行的道路。道路被用来连接N个牧场,牧场被连续地编号为1到N。每一个牧场都是一个奶牛的家。FJ计划除去P条道路中尽可能多的道路,但是还要保持牧场之间 的连通性。你首先要决定那些道路是需要保留的N-1条道路。第j条双向道路连接了牧场Sj和Ej(1 <= Sj <= N; 1 <= Ej <= N; Sj != Ej),而且走完它需要Lj的时间。没有两个牧场是被一条以上的道路所连接。奶牛们非常伤心,因为她们的交通系统被削减了。你需要到每一个奶牛的住处去安慰她们。每次你到达第i个牧场的时候(即使你已经到过),你必须花去Ci的时间和奶牛交谈。你每个晚上都会在同一个牧场(这是供你选择的)过夜,直到奶牛们都从悲伤中缓过神来。在早上
起来和晚上回去睡觉的时候,你都需要和在你睡觉的牧场的奶牛交谈一次。这样你才能完成你的 交谈任务。假设Farmer John采纳了你的建议,请计算出使所有奶牛都被安慰的最少时间。
题目的测试样例有误:(P为7怎么才6组。。我把题目的7改为6答案为178)
5 6
10
10
20
6
30
1 2 5
2 3 5
2 4 12
3 4 17
2 5 15
3 5 6
思路:
直接把边的权值w(u,v)改为2*w(u,v)+cost[u]+cost[v],然后求MST。why?
纸上画画这组数据(答案43)
3 2
5 6 7
1 2 3
2 3 4
然后因为他要找一个地方过夜,所以要多花费一个点的对话,找最小的地方过夜就好了~嘻嘻~
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXN=10000+10; const int MAXM=100000+10; const int INF=100000; int cost[MAXN],fa[MAXN]; int find(int cur) { return cur==fa[cur]? cur:fa[cur]=find(fa[cur]); } struct edge { int from,to,val; bool operator <(const edge& x)const{ return val<x.val; } }e[MAXM]; int main() { int mini=INF,index; int n,p; scanf("%d%d",&n,&p); for(int i=1;i<=n;i++) { scanf("%d",&cost[i]); mini=min(cost[i],mini); fa[i]=i; } for(int i=0;i<p;i++) { scanf("%d%d%d",&e[i].from,&e[i].to,&e[i].val); e[i].val=(e[i].val<<1)+cost[ e[i].from ] + cost [ e[i].to ]; } sort(e,e+p); int ans=0; for(int i=0;i<p;i++) { int x=e[i].from,y=e[i].to; int root_x=find(x),root_y=find(y); if(root_x==root_y) continue; fa[root_x]=root_y; ans+=e[i].val; } printf("%d\n",ans+mini); return 0; }
算法训练- 最短路
给定一个n个顶点,m条边的有向图(其中某些边权可能为负,但保证没有负环)。请你计算从1号点到其他点的最短路(顶点从1到n编号)。
直接SPFA,直接100分。。
开锦囊说堆优化的dijkstra。。。题目有负边权啊!你确定这不是临时工写的?还是我水平有限?望赐教。。。
#include<cstdio> #include<queue> #include<cstring> using namespace std; const int MAXN=20000+10; const int MAXM=200000+10; const int INF=100000; int head[MAXN],len,dis[MAXN],n,m; bool vis[MAXN]; struct edge { int to,val,next; }e[MAXM]; void add(int from,int to,int val) { e[len].to=to; e[len].val=val; e[len].next=head[from]; head[from]=len++; } queue<int> q; void spfa() { for(int i=1;i<=n;i++) dis[i]=INF; memset(vis,0,sizeof(vis)); q.push(1); vis[1]=true; dis[1]=0; while(!q.empty()) { int cur=q.front(); q.pop(); vis[cur]=false; for(int i=head[cur];i!=-1;i=e[i].next) { int id=e[i].to; if(dis[id] > dis[cur] + e[i].val) { dis[id] = dis[cur] + e[i].val; if(!vis[id]) { vis[id]=true; q.push(id); } } } } } int main() { memset(head,-1,sizeof(head)); len=0; scanf("%d%d",&n,&m); for(int i=0;i<m;i++) { int from,to,val; scanf("%d%d%d",&from,&to,&val); add(from,to,val); } spfa(); for(int i=2;i<=n;i++) printf("%d\n",dis[i]); return 0; }
原文:http://blog.csdn.net/murmured/article/details/19292147