zoukankan      html  css  js  c++  java
  • poj 1679 The Unique MST

    题目要判断最小生成树是不是是唯一的。

    先用prim算法求出最小生成树。然后将加进最小生成树的边用used数组标记起来,并且记录下i-j点的最大权值。然后在枚举那些没加进生成树的边。看是否也能得到同样的权值。如果能说明不唯一

    比如used[i][j]==0说明i-j这条边没加进去然后更新Min。

    #include<stdio.h>
    #include<string.h> 
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int inf=0x3f3f3f3f;
    const int maxn=110;
    bool vis[maxn];
    int lowc[maxn];
    int cost[maxn][maxn];
    int pre[maxn];
    int Max[maxn][maxn];
    bool used[maxn][maxn];
    int n,m; 
    int ans;
    int Prim()
    {
       ans=0;
       memset(vis,false,sizeof(vis));
       memset(Max,0,sizeof(Max));
       memset(used,false,sizeof(used));
       vis[0]=true;
       pre[0]=-1;
       for(int i=1;i<n;i++)
       {
       	  lowc[i]=cost[0][i];
       	  pre[i]=0;
       }
       	lowc[0]=0;
       	for(int i=1;i<n;i++)
       	{
       		int min=inf; 	
    		int p=-1;
       		for(int j=0;j<n;j++)
       		{
       			if(!vis[j]&&min>lowc[j])
       			{
       				min=lowc[j];
       				p=j;
       			}
       		}
       		if(min==inf)
       		return -1;
       		ans+=min;
       		vis[p]=true;
       		used[p][pre[p]]=used[pre[p]][p]=true;
       		for(int j=0;j<n;j++)
    		   {
    		   	if(vis[j])
    		   	Max[p][j]=Max[j][p]=max(Max[j][pre[p]],lowc[p]);
    		   	if(!vis[j]&&lowc[j]>cost[p][j])
    		   	{
    		   		lowc[j]=cost[p][j];
    				pre[j]=p; 
    		   	}
    		   } 
       	}
       	return ans;
    } 
    int get_min()
    {
    	int Min=inf;
    	for(int i=0;i<n;i++)
    	{
    		for(int j=i+1;j<n;j++)
    		{
    			if(cost[i][j]!=inf&&!used[i][j])
    			{
    				Min=min(Min,ans+cost[i][j]-Max[i][j]);
    			}
    		}
    	}
    //	printf("%d
    ",Min);
    	if(Min==inf)
    	return -1;
    	return Min;
    	
    }
    int main()
    {
    	int t;
    	scanf("%d",&t);
    	while(t--)
    	{
    		scanf("%d%d",&n,&m);
    		for(int i=0;i<n;i++)
    		for(int j=0;j<n;j++)
    		{
    			if(i==j)
    			cost[i][j]=0;
    			cost[i][j]=inf; 
    		}
    		
    		for(int i=0;i<m;i++)
    		{
    			int u,v,w;
    			scanf("%d %d %d",&u,&v,&w);
    			u--;
    			v--;
    			cost[u][v]=w;
    			cost[v][u]=w;
    		}
       int ans=Prim();
      // printf("%d
    ",ans);
       if(ans==-1)
       printf("Not Unique!
    ");
       else if(ans==get_min())
       printf("Not Unique!
    ");
       else
       printf("%d
    ",ans);
    	}
    	return 0;
    } 


  • 相关阅读:
    8.10
    今日头条笔试题 1~n的每个数,按字典序排完序后,第m个数是什么?
    Gym 100500B Conference Room(最小表示法,哈希)
    CodeForces 438D The Child and Sequence(线段树)
    UVALIVE 6905 Two Yachts(最小费用最大流)
    Gym Conference Room (最小表示法,哈希)
    hdu 2389 Rain on your Parade(二分图HK算法)
    Codeforces Fox And Dinner(最大流)
    zoj 3367 Counterfeit Money(dp)
    ZOJ3370. Radio Waves(2-sat)
  • 原文地址:https://www.cnblogs.com/NaCl/p/9580106.html
Copyright © 2011-2022 走看看