luogu1396 二分答案或者並查集水題

有m條大道連接n個區,一條大道將兩個區相連接,每個大道有一個擁擠度。小明的媽媽雖然很着急,但是不願意擁擠的人潮衝亂了她優雅的步伐。所以請你幫她規劃一條從s至t的路線,使得經過道路的擁擠度最大值最小。

首先是二分答案做法:

#include<iostream>
#include<cstdio>
#include<algorithm>
const int maxn=50000+10;
using namespace std;
int to[maxn],next[maxn],beg[maxn],w[maxn],e,mid,s,t,p[maxn];
void add(int x,int y,int z){
	to[++e]=y;
	next[e]=beg[x];
	beg[x]=e;
	w[e]=z;
}
bool dfs(int x){		
	p[x]=1;
	if(x==t)return true;
	for(int i=beg[x];i;i=next[i])
		if(!p[to[i]] && w[i]<=mid)
			if(dfs(to[i]))return true;			
	return false;
}
int main(){
	int i,j,k,m,n;
	cin>>n>>m>>s>>t;
	for(i=1;i<=m;i++){
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		add(x,y,z);
		add(y,x,z);
	}
	int l=0,r=10000;
	while(l<r){
		mid=(l+r)/2;
		for(i=1;i<=n;i++)p[i]=0;		
		if(dfs(s))r=mid;
		else l=mid+1;	
	}
	cout<<l<<endl;
	return 0;
}

下面是weaTao寫的並查集做法:

#include<bits/stdc++.h>
using namespace std;
const int maxn=10010;
struct Edge{
    int u,v,w;
}e[maxn<<1];
int fa[maxn];
void Read ( int &x ) {
    x = 0 ; char c = getchar() ;
    while ( c < '0' || c > '9' ) c = getchar() ;
    while ( c >= '0' && c <= '9' ) {
        x = 10 * x + c - '0' ;
        c = getchar() ;
    }
}
bool cmp(Edge a,Edge b){
    return a.w<b.w;
}
int father(int x){
    return fa[x]=x==fa[x]?x:father(fa[x]);
}
int main(){
    int i,j,k,m,n,s,t;
    Read(n) ;
    Read(m) ;
    Read(s) ;
    Read(t) ;
    for(i=1;i<=m;i++){
        int x,y,z;
        Read(x) ;
        Read(y) ;
        Read(z) ;
        e[i]=(Edge){x,y,z};
    }
    
    for(i=1;i<=n;i++)fa[i]=i;
    
    sort(e+1,e+m+1,cmp);
    
    for(i=1;i<=m;i++){
        int x=e[i].u,y=e[i].v;
        if(father(x)!=father(y)){
            fa[father(x)]=father(y);
        }
        if(father(s)==father(t))break;
    }
    
    printf("%d\n",e[i].w);
    
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章