1. 程式人生 > >嚶嚶嚶 (並查集+列舉)

嚶嚶嚶 (並查集+列舉)

Our lovely KK has a difficult Social problem.
A big earthquake happened in his area.
N(2≤N≤2000)N(2≤N≤2000) cities have been implicated. All the roads between them are destroyed.
Now KK was commissioned to rebuild these roads.
However, after investigation,KK found that some roads are too damaged to rebuild.
Therefore, there are only M(0≤M≤15000)M(0≤M≤15000) roads can be rebuilt.
KK needs to make sure that there is a way between any two cities, and KK wants to rebuild roads as few as possible.
With rebuilding minimal number of roads, he also wants to minimize the difference between the price of the most expensive road been built and the cheapest one.

Input

The first line of the input file contains an integer T(1≤T≤10)T(1≤T≤10), which indicates the number of test cases.

For each test case,The first line includes two integers N(2≤N≤2000)N(2≤N≤2000),M(0≤M≤15000)M(0≤M≤15000).

The next MM lines include three integers a,b,c(a≠b,1≤c≤2∗109)a,b,c(a≠b,1≤c≤2∗109),indicating there is a undirected edge between aa and bb,the cost is cc.

Output

For each test case, output the smallest difference between the price of the most expensive road and the cheapest one.If there is no legal solution, then output -1.

Sample Input

2
5 10
1 2 9384
1 3 887
1 4 2778
1 5 6916
2 3 7794
2 4 8336
2 5 5387
3 4 493
3 5 6650
4 5 1422
2 0

Sample Output

1686
-1

題解:這道題的時間給的是6s,排完序後所以可以列舉每一種修路的情況,但是如果把所有的情況都存在數組裡會溢位,就只把最貴的和最便宜的放陣列然後做差,然後找到最小的。

此題坑點有主要有二:

1,存所有情況陣列溢位

2,定義那個較大的數一定要儘量大(在比較求差值最小的時候)

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int pre[100005];
struct node
{
	int x,y;
	long long int val;
}road[200005];
int find(int x)
{
	if(x==pre[x])
	return x;
	else
	{
		return pre[x]=find(pre[x]);
	}
}
bool merge(int x,int y)
{
	int fx=find(x);
	int fy=find(y);
	if(fx!=fy)
	{
		pre[fx]=fy;
		return true;	
	}
	else
	{
		return false;
	}
}
bool cmp(node x,node y)
{
	return x.val<y.val;
}
int main()
{
	int n;
	cin>>n;
   while(n--)
	{
		int m,s;
		cin>>m>>s;
		
   	for(int j=1;j<=m;j++)
    {
	 pre[j]=j;
	} 
	for(int t=1;t<=s;t++)
	{
	scanf("%d%d%d",&road[t].x,&road[t].y,&road[t].val);
    } 
    sort(road+1,road+s+1,cmp);
   long long  int cnt=0;
    int a[3000005];
    int crt=0; 
    int l=0;
    for(int t=1;t<=s;t++)
    {
    	
        for(int j=t;j<=s;j++)
        {
		
    	if(merge(road[j].x,road[j].y))
    	{
    	    if(cnt%(m-1)==m-2||(cnt%(m-1)==0))
	    {
	    	a[crt]=road[j].val;
	    	crt++;
		}
    		cnt++;
		}

	    
		if(cnt%(m-1)==0)
		{
			for(int k=1;k<=m;k++)
           {
	        pre[k]=k;
	       } 
	 	    break;
	    }
       	}
	}
    
	long long int Min=999999999;
	int k=0;
	if(crt%2==1){
	
	for(int t=0;t<crt-1;t=t+2)
	{  
		if(Min>a[t+1]-a[t])
		{
		Min=a[t+1]-a[t];
	    }
	
	}
     }
     else
     {
     		for(int t=0;t<crt;t=t+2)
	{  
		if(Min>a[t+1]-a[t])
		{
		Min=a[t+1]-a[t];
	    }
	
	}
	 }
	    if(cnt>=m-1)
	    {
		
		printf("%lld\n",Min);
	}
	 else
	 {
	 	printf("-1\n");
	 }
	 
	} 
	return 0;
}