Span【推荐】

Description
  某国有N个村子,M条道路,为了实现“村村通工程”现在要”油漆”N-1条道路(因为某些人总是说该国所有的项目全是从国外进口来的,只是漆上本国的油漆罢了),因为“和谐”是此国最大的目标和追求,以致于对于最小造价什么的都不在乎了,只希望你所选出来的最长边与最短边的差越小越好。
Input
  第一行给出一个数字TOT,代表有多少组数据,Tot<=6
  对于每组数据,首先给出N,M
  下面M行,每行三个数a,b,c代表a村与b的村道路距离为c.
Output
  输出最小差值,如果无解输出”-1”.
Sample Input
1
4 5
1 2 3
1 3 5
1 4 6
2 4 6
3 4 7
Sample Output
1

The solution

先把边按长度排序,然后枚举最长边,再从大到小加边,直到实现连得边数为n-1,
最后加入的边即为此最长边对应的最短边。
之后再统计答案就好了
加边时用并查集维护。

比赛时BB地把输出放在多组数据之外了,然后就GG了 o(╯□╰)o
还有许多的低级错误,比如j写成i,对于新的一组数据,忘了赋值成INF

总之各种BB。。。原本可以ac的,却QAQ了/(ㄒoㄒ)/~~。
下次要吸取教训。。

Code

#include 
#include 
#include 
#include 
#include 
#define fo(i,a,b) for (int i=a;i<=b;i++)
#define fd(i,a,b) for (int i=a;i>=b;i--)
#define N 50000
#define INF 2147483647
using namespace std;
struct note
{
    int x,y,z;
}a[N];
int Dad[N];
int T,n,m,ans;
int get(int x) {return x==Dad[x]?x:(Dad[x]=get(Dad[x]));}
bool cmp(note a,note b){return a.z>b.z;}
int main()
{
    freopen("data.in","r",stdin);
    scanf("%d",&T);
    while (T--)
    {
        ans=INF;
        scanf("%d%d",&n,&m);
        fo(i,1,m) 
            scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
        sort(a+1,a+1+m,cmp);
        fo(i,1,m) 
        {
            fo(j,1,n) Dad[j]=j;
            int tot=0;
            fo(j,i,m)
            {
                int xx=get(a[j].x),yy=get(a[j].y);
                if (xx!=yy)
                {
                    Dad[xx]=yy;
                    tot++;
                    if (tot==n-1)
                    {
                        ans=min(ans,a[i].z-a[j].z);
                        break;
                    }
                }
            }
        }
        if (ans!=INF)
        printf("%d\n",ans); else printf("-1\n");
    }   
    return 0;
}

你可能感兴趣的:(并查集)