70.最小生成树
2016-03-12 22:58
288 查看
删边问题(edges.pas)
题目描述:连通图是指任意两个顶点都有路径可互相到达的图。
读入一个无向的连通图,输出最多能删掉多少条边,使这个图仍然连通。
输入格式:
第一行为图的顶点数N(1<=N<=100)和边数M,它们之间用一个空格隔开,图中的顶点用1到N的整数标号。接下来的M行,每行用两个数v1和v2表示一条边。v1和v2用一个空格隔开,表示这条边所连接的顶点的标号(v1<>v2),同一条边不会重复出现。
输出格式:
输出最多能删掉的边数。
输入输出样例:
思路:寻找最小生成树,用总边数目减去最小生成树中的边的数目,直接用
总边数-n+1就行了
代码:
#include
#include
using namespace std;
#include
struct Edge{
int u,v,w,next;
};
Edge edge[1001];
int head[1001]={0},father[1001];
int visit[1001]={0},n,m,sum=0;//
int cmp(const Edge &a,const Edge &b)
{
return a.w
}
void input()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;++i)
{
scanf("%d%d",&edge[i].u,&edge[i].v);
edge[i].w=i;
edge[i].next=head[edge[i].u];
head[edge[i].u]=i;
}
}
int find(int x)
{
if(father[x]!=x) father[x]=find(father[x]);
return father[x];
}
int k;
void unionn(int a,int b)
{
father[b]=a;
}
void kruskal()
{
k=0;
sort(edge+1,edge+m+1,cmp);
for(int i=1;i<=n;++i)
father[i]=i;
for(int i=1;i<=m;++i)
{
int r1=find(edge[i].u);
int r2=find(edge[i].v);
if(r1!=r2)
{
k++;
unionn(r1,r2);
sum++;
if(k==n-1) break;
}
}
}
int main()
{
input();
kruskal();
if(k==n-1)//表示图能连通
,一定是n-1条边
cout<<m-sum<<endl;
else cout<<"no way!"<<endl;//
return 0;
}
题目描述:连通图是指任意两个顶点都有路径可互相到达的图。
读入一个无向的连通图,输出最多能删掉多少条边,使这个图仍然连通。
输入格式:
第一行为图的顶点数N(1<=N<=100)和边数M,它们之间用一个空格隔开,图中的顶点用1到N的整数标号。接下来的M行,每行用两个数v1和v2表示一条边。v1和v2用一个空格隔开,表示这条边所连接的顶点的标号(v1<>v2),同一条边不会重复出现。
输出格式:
输出最多能删掉的边数。
输入输出样例:
输入edges.in | 输出 edges.out |
4 6 1 2 1 3 1 4 2 3 2 4 3 4 | 3 |
总边数-n+1就行了
代码:
#include
#include
using namespace std;
#include
struct Edge{
int u,v,w,next;
};
Edge edge[1001];
int head[1001]={0},father[1001];
int visit[1001]={0},n,m,sum=0;//
int cmp(const Edge &a,const Edge &b)
{
return a.w
}
void input()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;++i)
{
scanf("%d%d",&edge[i].u,&edge[i].v);
edge[i].w=i;
edge[i].next=head[edge[i].u];
head[edge[i].u]=i;
}
}
int find(int x)
{
if(father[x]!=x) father[x]=find(father[x]);
return father[x];
}
int k;
void unionn(int a,int b)
{
father[b]=a;
}
void kruskal()
{
k=0;
sort(edge+1,edge+m+1,cmp);
for(int i=1;i<=n;++i)
father[i]=i;
for(int i=1;i<=m;++i)
{
int r1=find(edge[i].u);
int r2=find(edge[i].v);
if(r1!=r2)
{
k++;
unionn(r1,r2);
sum++;
if(k==n-1) break;
}
}
}
int main()
{
input();
kruskal();
if(k==n-1)//表示图能连通
,一定是n-1条边
cout<<m-sum<<endl;
else cout<<"no way!"<<endl;//
return 0;
}
相关文章推荐
- 第二周作业
- zookeeper 学习命令
- 70.最小生成树
- 70.最小生成树
- vbscript基础1
- 设计模式之观察者模式
- 解决HttpClient访问返回403 forbiddent
- HDU——1042N!(大数阶乘乘法)
- C++学习笔记之多态与虚函数,虚函数表
- chart.js绘图,如何显示图例?
- 20145330孙文馨 《Java程序设计》第二周学习总结
- 测试
- LintCode : Find Minimum in Rotated Sorted Array
- 正则表达式与grep命令
- websocket
- 诈骗电话整理
- FLV文件(H264 + AAC)格式超详细分析
- 执行上下文和执行上下文堆栈
- CSS3 Background-clip
- 二、fragment使用