畅通工程 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 38345 Accepted Submission(s): 17093
Problem Description 省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。 Input 测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M ( < 100 );随后的 N 行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。 Output 对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“?”。 Sample Input 3 3 1 2 1 1 3 2 2 3 4 1 3 2 3 2 0 100 Sample Output 3 ? Source 浙大计算机研究生复试上机考试-2007年 Recommend lcy | We have carefully selected several similar problems for you: 1879 1233 1875 1232 1102 今天是图论集训第一天,以前讲数据结构图的时候,对图怕怕的,但怕又能怎样?只有坦然面对,有意思的东西固然难,加油,蓝孩,为了你的Jeep,加油! #include<iostream> #include<algorithm> #include<string.h> using namespace std; struct kk { int s,e,w; }; int Prim(int N,int M) { kk a[10000]; int i,j,pos=1,min,flag=0,result=0,map[101][101],low[101],visit[101]; low数组存当前到各个顶点的最小权值 memset(map,0x3f3f3f3f,sizeof(map)); 将邻接矩阵设为无穷大 memset(visit,0,sizeof(visit)); for(i=0;i<N;i++) { scanf("%d%d%d",&a[i].s,&a[i].e,&a[i].w); map[a[i].s][a[i].e]=a[i].w; map[a[i].e][a[i].s]=a[i].w; } visit[pos]=1; for(i=1;i<=M;i++) { if(!visit[i]) low[i]=map[pos][i]; } for(i=0;i<M-1;i++) { min=0x3f3f3f3f; for(j=1;j<=M;j++) { if(!visit[j]&&low[j]<min) { min=low[j]; pos=j; } } result+=min; visit[pos]=1; for(j=1;j<=M;j++) { if(!visit[j]&&low[j]>map[pos][j]) { low[j]=map[pos][j]; } } } for(i=1;i<=M;i++) { if(visit[i]==0) { flag=1; break; } } if(flag==1) return 0; else return result; } int main() { int n,m; while(~scanf("%d%d",&n,&m)) { if(n==0) break; int t=Prim(n,m); if(t==0) cout<<"?"<<endl; else cout<<t<<endl; } return 0; } 下面是克鲁斯卡尔算法 #include<iostream> #include<string> #include<algorithm> using namespace std; struct kk { int s,e,w; }s[10009]; int a[105]; int cmp(kk x,kk y) { return x.w<y.w; } int find(int x) { return x==a[x]?x:a[x]=find(a[x]); } int join(int x,int y) { int fx=find(x); int fy=find(y); if(fx!=fy) { a[fx]=fy; return 1; } else return 0; } int main() { int i,j,n,m; //freopen("1.txt","r",stdin); while(~scanf("%d%d",&n,&m)) { if(n==0) break; int f=0,sum=0; for(i=1;i<=n;i++) cin>>s[i].s>>s[i].e>>s[i].w; for(i=1;i<=m;i++) a[i]=i; sort(s+1,s+n+1,cmp); for(i=1;i<=n;i++) { if(join(s[i].s,s[i].e)) { f++; sum+=s[i].w; } if(f==m-1) break; } if(f==m-1) cout<<sum<<endl; else cout<<"?"<<endl; } return 0; } |