1083: [SCOI2005]繁忙的都市
Description
城市C是一个非常繁忙的大都市,城市中的道路十分的拥挤,于是市长决定对其中的道路进行改造。城市C的道
路是这样分布的:城市中有n个交叉路口,有些交叉路口之间有道路相连,两个交叉路口之间最多有一条道路相连
接。这些道路是双向的,且把所有的交叉路口直接或间接的连接起来了。每条道路都有一个分值,分值越小表示这
个道路越繁忙,越需要进行改造。但是市政府的资金有限,市长希望进行改造的道路越少越好,于是他提出下面的
要求: 1. 改造的那些道路能够把所有的交叉路口直接或间接的连通起来。 2. 在满足要求1的情况下,改造的
道路尽量少。 3. 在满足要求1、2的情况下,改造的那些道路中分值最大的道路分值尽量小。任务:作为市规划
局的你,应当作出最佳的决策,选择那些道路应当被修建。
Input
第一行有两个整数n,m表示城市有n个交叉路口,m条道路。接下来m行是对每条道路的描述,u, v, c表示交叉
路口u和v之间有道路相连,分值为c。(1≤n≤300,1≤c≤10000)
Output
两个整数s, max,表示你选出了几条道路,分值最大的那条道路的分值是多少。
Sample Input
4 5
1 2 3
1 4 5
2 4 7
2 3 6
3 4 8
1 2 3
1 4 5
2 4 7
2 3 6
3 4 8
Sample Output
3 6
看题目第一眼就知道是个二分答案然后判断。。。根据题意实际上我们选出来的是一个树。。。那么做kruskal就好了。。。但是在写代码的时候我发现我们并不需要二分答案。。。
只要确保边权递增,从小到大加边,当加了n-1条边时,当前边就是答案了。。。
1 #include<iostream> 2 #include<cstdlib> 3 #include<cmath> 4 #include<cstring> 5 #include<cstdio> 6 #include<algorithm> 7 #include<string> 8 #include<map> 9 #include<queue> 10 #include<vector> 11 #include<set> 12 #define inf 1000000000 13 #define maxn 10000+5 14 #define maxm 10000+5 15 #define eps 1e-10 16 #define ll long long 17 #define for0(i,n) for(int i=0;i<=(n);i++) 18 #define for1(i,n) for(int i=1;i<=(n);i++) 19 #define for2(i,x,y) for(int i=(x);i<=(y);i++) 20 #define for3(i,x,y) for(int i=(x);i>=(y);i--) 21 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go) 22 using namespace std; 23 int read(){ 24 int x=0,f=1;char ch=getchar(); 25 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 26 while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();} 27 return x*f; 28 } 29 int fa[maxn],n,m,ans,tot; 30 struct edge{ 31 int u,v,w; 32 }e[maxm]; 33 bool cmp(edge a,edge b){ 34 return a.w<b.w; 35 } 36 int find(int x){ 37 return fa[x]==x?x:fa[x]=find(fa[x]); 38 } 39 int main(){ 40 //freopen("input.txt","r",stdin); 41 //freopen("output.txt","w",stdout); 42 n=read();m=read(); 43 for1(i,m){ 44 e[i].u=read();e[i].v=read();e[i].w=read(); 45 } 46 sort(1+e,e+m+1,cmp); 47 for1(i,n)fa[i]=i; 48 for1(i,m){ 49 int x=find(e[i].u),y=find(e[i].v); 50 if(x!=y){ 51 tot++; 52 fa[x]=y; 53 ans=e[i].w; 54 } 55 if(tot==n-1)break; 56 } 57 printf("%d %d",tot,ans); 58 return 0; 59 }