Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 39078 Accepted Submission(s): 17455 Problem Description The goal of the provincial government's "unblocking project" is to make highway traffic possible between any two villages in the province (but there is not necessarily a direct highway connection, as long as it can be reached indirectly through the highway). After investigation and evaluation, the cost of several roads that may be constructed is listed in the statistical table. Now, please write a program to calculate the lowest cost for the smooth flow of the whole province.
Input The test input contains several test cases. The first line of each test case shows the number of evaluated roads N, the number of villages m (< 100); the next N
Output For each test case, output the lowest cost required for smooth operation of the whole province in one line. If the statistics are not enough to ensure smooth flow, output "?".
Sample Input |
3 3 1 2 1 1 3 2 2 3 4 1 3 2 3 2 0 100
Sample Output |
3 ?
Two algorithms.
Kruskal algorithm:
#include<bits/stdc++.h> using namespace std; const int maxn = 1e3+10; int pre[maxn]; struct inp{ int u; int v; int w; }p[maxn]; bool cmp(inp a,inp b) { return a.w<b.w; } int find(int x) //Recursively find the boss of this function every time { //return pre[x]==x?x:find(pre[x]); if(pre[x]==x) return x; return find(pre[x]); } void join(int x,int y) //merge { int fx = find(x); int fy = find(y); if(fx!=fy) pre[fx]=fy; } int main() { int n,m,ans; while(cin>>m>>n && m) { ans=0; for(int i=1;i<=n;i++) pre[i]=i; //Initialization cannot be forgotten for(int i=1;i<=m;i++) cin>>p[i].u>>p[i].v>>p[i].w; sort(p+1,p+m+1,cmp); for(int i=1;i<=m;i++) //Core operation { if(find(p[i].u)!=find(p[i].v)) { ans+=p[i].w; join(p[i].u,p[i].v); } } int flag=0; for(int i=1;i<=n;i++) { if(find(1)!=find(i)) { flag=1; break; } } if(flag==1) cout<<"?"<<endl; else cout<<ans<<endl; } return 0; }
Prim algorithm:
#include<bits/stdc++.h> using namespace std; const int maxn = 1e3+10; const int inf = 0x3f3f3f3f; int m[maxn][maxn]; int vis[maxn],dis[maxn]; int n,u,v,w,r; void prim() { memset(vis,0,sizeof(vis)); int ans,next,ans1=0; for(int i=1;i<=n;i++) dis[i]=m[1][i]; vis[1]=1; for(int i=1;i<n;i++) { ans=inf; for(int j=1;j<=n;j++)//The purpose of this layer of for loop is to find the closest point to the effective set { if(!vis[j] && dis[j]<ans) { ans=dis[j]; next = j; } } if(ans==inf) { cout<<"?"<<endl; return ; //End procedure } ans1+=ans; vis[next]=1; for(int j=1;j<=n;j++)//This layer of for loop is to update the minimum value (including the point just incorporated) { if(!vis[j] && dis[j]>m[next][j]) dis[j] = m[next][j]; } } cout<<ans1<<endl; } int main() { while(cin>>r>>n && r) { memset(m,inf,sizeof(m)); for(int i=1;i<=r;i++) { cin>>u>>v>>w; m[u][v]=m[v][u]=w; } prim(); } return 0; }