Problem H
2016-07-05 15:50
218 查看
[align=left]Problem Description[/align]
In graph theory, a pseudoforest is an undirected graph in which every connected component has at most one cycle. The maximal pseudoforests of G are the pseudoforest subgraphs of G that are not contained within any larger pseudoforest
of G. A pesudoforest is larger than another if and only if the total value of the edges is greater than another one’s.<br><br>
[align=left]Input[/align]
The input consists of multiple test cases. The first line of each test case contains two integers, n(0 < n <= 10000), m(0 <= m <= 100000), which are the number of the vertexes and the number of the edges. The next m lines, each line
consists of three integers, u, v, c, which means there is an edge with value c (0 < c <= 10000) between u and v. You can assume that there are no loop and no multiple edges.<br>The last test case is followed by a line containing two zeros, which means the
end of the input.<br>
[align=left]Output[/align]
Output the sum of the value of the edges of the maximum pesudoforest.<br>
[align=left]Sample Input[/align]
3 3
0 1 1
1 2 1
2 0 1
4 5
0 1 1
1 2 1
2 3 1
3 0 1
0 2 2
0 0
[align=left]Sample Output[/align]
3
5
代码: #include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
const int maxn = 10005;
const int maxm = 100005;
struct node{
int u,v,val;
}edge[ maxm ];
int fa[ maxn ],circle[ maxn ];
int find( int x ){
if( fa[x]==x ) return x;
fa[x] = find(fa[x]);
return fa[x];
}
bool union_ab( int x,int y ){
int fax = find(x);
int fay = find(y);
if( fax==fay ){
if( circle[ fax ]==-1 ){
circle[ fax ] = 1;
return true;
}//形成一个环
return false;
//已经是环
}
else{
if( circle[ fax ]==circle[ fay ]&&circle[ fax ]==1 )
return false;
if( circle[ fax ]==1 )
fa[ fay ] = fax;
else
fa[ fax ] = fay;
//这里注意把环作为祖先,因为find
return true;
}
}
void init( int n ){
for( int i=0;i<n;i++ ){
fa[i] = i;
circle[ i ] = -1;
}
}
int cmp( node a,node b ){
return a.val>b.val;
}
int main(){
int n,m;
while( scanf("%d%d",&n,&m)==2,n||m ){
//if( n==0&&m==0 ) break;
for( int i=0;i<m;i++ )
scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].val);
init( n );
sort( edge,edge+m,cmp );
int ans = 0;
for( int i=0;i<m;i++ ){
if( union_ab( edge[i].u,edge[i].v) )
ans += edge[i].val;
}
printf("%d\n",ans);
}
return 0;
}
In graph theory, a pseudoforest is an undirected graph in which every connected component has at most one cycle. The maximal pseudoforests of G are the pseudoforest subgraphs of G that are not contained within any larger pseudoforest
of G. A pesudoforest is larger than another if and only if the total value of the edges is greater than another one’s.<br><br>
[align=left]Input[/align]
The input consists of multiple test cases. The first line of each test case contains two integers, n(0 < n <= 10000), m(0 <= m <= 100000), which are the number of the vertexes and the number of the edges. The next m lines, each line
consists of three integers, u, v, c, which means there is an edge with value c (0 < c <= 10000) between u and v. You can assume that there are no loop and no multiple edges.<br>The last test case is followed by a line containing two zeros, which means the
end of the input.<br>
[align=left]Output[/align]
Output the sum of the value of the edges of the maximum pesudoforest.<br>
[align=left]Sample Input[/align]
3 3
0 1 1
1 2 1
2 0 1
4 5
0 1 1
1 2 1
2 3 1
3 0 1
0 2 2
0 0
[align=left]Sample Output[/align]
3
5
代码: #include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
const int maxn = 10005;
const int maxm = 100005;
struct node{
int u,v,val;
}edge[ maxm ];
int fa[ maxn ],circle[ maxn ];
int find( int x ){
if( fa[x]==x ) return x;
fa[x] = find(fa[x]);
return fa[x];
}
bool union_ab( int x,int y ){
int fax = find(x);
int fay = find(y);
if( fax==fay ){
if( circle[ fax ]==-1 ){
circle[ fax ] = 1;
return true;
}//形成一个环
return false;
//已经是环
}
else{
if( circle[ fax ]==circle[ fay ]&&circle[ fax ]==1 )
return false;
if( circle[ fax ]==1 )
fa[ fay ] = fax;
else
fa[ fax ] = fay;
//这里注意把环作为祖先,因为find
return true;
}
}
void init( int n ){
for( int i=0;i<n;i++ ){
fa[i] = i;
circle[ i ] = -1;
}
}
int cmp( node a,node b ){
return a.val>b.val;
}
int main(){
int n,m;
while( scanf("%d%d",&n,&m)==2,n||m ){
//if( n==0&&m==0 ) break;
for( int i=0;i<m;i++ )
scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].val);
init( n );
sort( edge,edge+m,cmp );
int ans = 0;
for( int i=0;i<m;i++ ){
if( union_ab( edge[i].u,edge[i].v) )
ans += edge[i].val;
}
printf("%d\n",ans);
}
return 0;
}
相关文章推荐
- Spring MVC之@RequestMapping 详解
- LDA java
- android 圆形进度条的简单实现
- 图片转word,誓死不当打字仔
- mysql 源代码学习 博客 [lock..]
- 【oracle】 linux 下oracle 启动监听错误
- 利用CAS算法实现通用线程安全状态机
- Socket通信原理探讨(C++为例)
- C#学习笔记之正则表达式
- 读JavaScript语言精粹后部分知识的总结
- [置顶] Android开发之数据存储——SharedPreferences基础知识详解,饿补学会基本知识,开发者必会它的用法。
- [Linux] SPI 设备驱动模型(SPI 协议基础)
- 记一次使用Android studio修改代码不生效的问题
- 【struts2】<package>的配置
- ffmpeg多种码率控制方式的实现
- 集群:windows+was+ihs
- 如何删掉Portal中的无效内容
- 手把手教你做安豆计算器(五)-优化资源的使用
- HDU 2389 Rain on your Parade (二分匹配)
- 微信公众号token的asp.net脚本