poj 1679 判断最小生成树是否唯一
2013-08-19 18:47
344 查看
昨天一直WA,仔细看了下,是最小生成树的写法问题,路径记录的不正确,以后果断换种写法
我的做法是先求最小生成树,再枚举树边去掉,再求最小生成树,看是否还是相同的结果,如果是,则证明不唯一
View Code
另一种方法,先求最小生成树,再广搜或深搜求任意两点间的最大树边,再枚举不在树上的边,判断是否存在某条不是树边的边的权值等于所连两点间的最大树边,如果有,则不唯一,因为替换之后还是最小生成树,且总权值不变
View Code
我的做法是先求最小生成树,再枚举树边去掉,再求最小生成树,看是否还是相同的结果,如果是,则证明不唯一
View Code
1 #include<stdio.h> 2 #include<string.h> 3 #include<vector> 4 #define M 110 5 using namespace std; 6 vector<int> edge[110]; 7 int map[110][110]; 8 const int inf = 9999999; 9 int vis[110],lowc[110]; 10 bool flag[M]; 11 double D[M]; 12 int pre[M]; 13 int prime(int s,int n,bool truth) 14 { 15 int i,v,k; 16 int mi; 17 int ret=0; 18 for(i=1;i<=n;i++) 19 { 20 flag[i]=0; 21 D[i]=inf; 22 pre[i]=-1; 23 } 24 D[s]=0; 25 for(k=0;k<n;k++) 26 { 27 mi=inf; 28 for(i=1;i<=n;i++)if(!flag[i]) 29 { 30 if(D[i]<mi) 31 { 32 mi=D[i]; 33 v=i; 34 } 35 } 36 ret+=mi; 37 flag[v]=1; 38 if(truth) 39 { 40 if(pre[v]!=-1) 41 { 42 edge[pre[v]].push_back(v); 43 } 44 } 45 for(i=1;i<=n;i++)if(!flag[i]) 46 { 47 if(map[v][i]<D[i]) 48 { 49 D[i]=map[v][i]; 50 if(truth) pre[i]=v; 51 } 52 } 53 } 54 return ret; 55 } 56 int main() 57 { 58 int t,i,j; 59 int n,m,x,y,w; 60 scanf("%d",&t); 61 while(t--) 62 { 63 scanf("%d%d",&n,&m); 64 for(i=0;i<=n;i++) 65 { 66 map[i][i]=0; 67 for(j=i+1;j<=n;j++) 68 map[j][i]=map[i][j]=inf; 69 } 70 for(i=0;i<m;i++) 71 { 72 scanf("%d%d%d",&x,&y,&w); 73 map[x][y]=map[y][x]=w; 74 } 75 for(i=0;i<=n;i++) 76 edge[i].clear(); 77 int ans=prime(1,n,true); 78 int flag=0; 79 for(int s=1;s<=n;s++) 80 { 81 for(j=0;j<edge[s].size();j++) 82 { 83 int t=edge[s][j]; 84 int tmp=map[s][t]; 85 map[s][t]=map[t][s]=inf;//去掉每一条生成树的边 86 int temp=prime(1,n,false); 87 map[t][s]=map[s][t]=tmp; 88 if(temp==ans) 89 { 90 flag=1; 91 break; 92 } 93 } 94 if(flag) break; 95 } 96 if(flag) printf("Not Unique!\n"); 97 else printf("%d\n",ans); 98 } 99 return 0; 100 } 101
另一种方法,先求最小生成树,再广搜或深搜求任意两点间的最大树边,再枚举不在树上的边,判断是否存在某条不是树边的边的权值等于所连两点间的最大树边,如果有,则不唯一,因为替换之后还是最小生成树,且总权值不变
View Code
1 #include<string.h> 2 #include<stdio.h> 3 #include<vector> 4 #include<math.h> 5 #include<queue> 6 using namespace std; 7 const int M =1010; 8 const int inf = 1000000; 9 int max(int a,int b){return a>b?a:b;} 10 int min(int a,int b){return a<b?a:b;} 11 int n,k,m; 12 int used[M]; 13 int di[M][M],cost[M][M]; 14 vector<int> edge[M]; 15 bool flag[M]; 16 int D[M]; 17 int pre[M]; 18 int prime(int s,int n) 19 { 20 int i,v,k; 21 int mi; 22 int ret=0; 23 for(i=1;i<=n;i++) 24 { 25 flag[i]=0; 26 D[i]=inf; 27 pre[i]=-1; 28 } 29 D[s]=0; 30 for(k=0;k<n;k++) 31 { 32 mi=inf; 33 for(i=1;i<=n;i++)if(!flag[i]) 34 { 35 if(D[i]<mi) 36 { 37 mi=D[i]; 38 v=i; 39 } 40 } 41 ret+=mi; 42 flag[v]=1; 43 if(pre[v]!=-1) 44 { 45 edge[pre[v]].push_back(v); 46 edge[v].push_back(pre[v]); 47 } 48 for(i=1;i<=n;i++)if(!flag[i]) 49 { 50 if(di[v][i]<D[i]) 51 { 52 D[i]=di[v][i]; 53 pre[i]=v; 54 } 55 } 56 } 57 return ret; 58 } 59 void bfs(int S) 60 { 61 int i,t; 62 queue<int> Q; 63 Q.push(S); 64 while(!Q.empty()) 65 { 66 int s=Q.front();Q.pop(); 67 used[s]=1; 68 for(i=0;i<edge[s].size();i++) 69 { 70 t=edge[s][i];if(used[t]) continue; 71 cost[S][t]=max(di[s][t],cost[S][s]); 72 Q.push(t); 73 } 74 } 75 } 76 int main() 77 { 78 int t,i,j; 79 int a,b,c; 80 scanf("%d",&t); 81 while(t--) 82 { 83 scanf("%d%d",&n,&m); 84 for(i=1;i<=n;i++) 85 { 86 edge[i].clear(); 87 cost[i][i]=0; 88 di[i][i]=0; 89 for(j=i+1;j<=n;j++) 90 { 91 cost[j][i]=cost[i][j]=-1; 92 di[j][i]=di[i][j]=inf; 93 } 94 } 95 for(i=0;i<m;i++) 96 { 97 scanf("%d%d%d",&a,&b,&c); 98 di[a][b]=di[b][a]=c; 99 } 100 int mm=prime(1,n); 101 memset(used,0,sizeof(used)); 102 for(i=1;i<=n;i++) 103 { 104 memset(used,0,sizeof(used)); 105 bfs(i); 106 } 107 int nn=1; 108 for(i=1;i<=n;i++) 109 for(j=1;j<=n;j++) 110 if(i!=j&&i!=pre[j]&&j!=pre[i]&&di[i][j]==cost[i][j]) 111 nn=-1; 112 if(nn!=-1) printf("%d\n",mm); 113 else printf("Not Unique!\n"); 114 } 115 return 0; 116 }
相关文章推荐
- poj 1679 The Unique MST(判断最小生成树是否唯一)
- poj-1679 The Unique MST 判断最小生成树是否唯一
- poj 1679 The Unique MST (判断最小生成树是否唯一)
- poj1679 The Unique MST ——判断最小生成树是否唯一_kruscal算法
- poj1679(次小生成树判断最小生成树是否唯一)
- POJ 1679 The Unique MST 判断最小生成树是否唯一
- POJ 1679 The Unique MST(判断最小生成树是否唯一)
- POJ 1679 判断最小生成树是否唯一
- poj_1679_判断最小生成树是否唯一
- poj 1679 判断最小生成树是否唯一
- poj 1679 The Unique MST 判断最小生成树是否唯一 解题报告
- POJ 1679 The Unique MST(判断最小生成树是否唯一)
- POJ1679 The Unique MST(判断最小生成树是否唯一)
- POJ 1679 The Unique MST (prim判断最小生成树是否唯一)
- POJ 1679 The Unique MST(判断最小生成树是否唯一)
- poj 1679 The Unique MST (判断最小生成树是否唯一)
- POJ 1679 The Unique MST(判断最小生成树是否唯一)
- poj 1679 判断最小生成树是否唯一(kruskal)
- poj 1679 The Unique MST 判断最小生成树是否唯一(图论)
- POJ 1679 The Unique MST(判断最小生成树是否唯一)