poj1308

来源:互联网 发布:stm8 c语言编程 编辑:程序博客网 时间:2024/05/22 16:57

大致题目:给定若干条边,边为有向边<u,v>从u指向v,由此判断该图是否为一棵树。简单的并查集判断回路+树特性判定

分析如下:首先用并查集检查所有有向边组成的图是否存在回路。若存在回路则可以判定为不是树。同时在记录下来每个顶点的入度和出度,一个没有回路的图要成为树,充分必要条件:

1)有且仅有一个出度为1的顶点,即为根节点

2)其余顶点的入度均为1

下面是代码:168K+0MS

#include <stdio.h>#include <stdlib.h>#include <string.h>#define Max 1100 //设置最大顶点数#define Maxx(a,b) (a)>(b)?(a):(b) #define Min(a,b) (a)<(b)?(a):(b) int set[Max]; int indu[Max]; // 顶点入度bool flag[Max]; //标记顶点是否在图中int a,b;int find(int x){ //查+路径压缩int j=x;while(set[x]!=x)x=set[x];int temp;while(j!=x){temp=set[j];set[j]=x;j=temp;}return x;}int main(){    int Case=1;while(scanf("%d%d",&a,&b)){if(a<0 && b<0) //若a,b均小于0,则退出break;for(int i=1;i<Max;i++) //初始化set[i]=i;    memset(flag,0,sizeof(flag));//初始化为均不再图中memset(indu,0,sizeof(indu)); // 初始化图中顶点的入度均为0bool trag=true; //标记图中是否存在回路(假设为无向图)while(a!=0 && b!=0){if(trag){ //若目前还不存在回路int x=find(a),y=find(b); //查父亲节点if(x==y) // 若相同,则说明存在回路(这里为无向图回路)trag=false;else{ //若不相同set[Maxx(x,y)]=Min(x,y); //大并小flag[a]=flag[b]=true; //设置标记为在图中    indu[b]++;//入度增加}}scanf("%d%d",&a,&b);}if(!trag) //若存在回路printf("Case %d is not a tree.\n",Case++);else{ //不存在回路    int i,num=0;for(i=1;i<Max;i++) //判断在图中的顶点的入度是否满足上述的两个充分必要条件if(flag[i]){if(indu[i]>1)break;else if(indu[i]==0){num++;if(num>1) break;}}if(i<Max) //若不满足printf("Case %d is not a tree.\n",Case++);else //满足printf("Case %d is a tree.\n",Case++);}}return 0;}

 

0 0
原创粉丝点击