- 题目描述:我们把一个城市考虑为一个图, 街道为边, 路口为点. 路口标记为 0~N-1. 盗贼从一个点开始逃亡, 每一分钟走一条边. 不幸的是, 我们并不知道他逃往何处, 只能假设他每分钟都必须沿着一条边走, 不能停留但是可以反复经过. 警官想要知道是否存在一个时刻, 盗贼可能出现在城市中的任意路口.
- 输入描述:第一行, 整数T, 测试用例数. 每例第一行3个整数, 点数N<=1e5, 边数M<=5e5, 起点S. 接下来M行, 每行两个数字表示一条边.
- 输出描述:如果存在这样的时刻输出"YES", 否则"NO".
- 测试案例:
- 输入:
2 3 3 0 0 1 0 2 1 2 2 1 0 0 1
- 输出:
Case 1: YES Case 2: NO
- 题目分析与思考:图与起点,题目已告知,从起点出发,它到达每一个节点可能有很多种情况,有可能是奇数时间到达,也有可能是偶数时间到达,题目询问你是否有一个时刻使它可以到达任意地点,时刻是不确定,但是这个时刻必然是偶数时间奇数时间中的一种。题目提醒我们每一条路可以多次经过,也就是说,边可以经过任意次数,那有没有一种可能,我们第一次到达一个地点是偶数时间,经过探寻又回到这个地方,探寻的过程,应该经历图中的一个环,不过此的时时间是奇数时间,这时你就会发现,任意一个节点,经过这个环的调节,都能在固定的时间到达。原理:这个环,一次经过需要奇数时间,那么,想要奇数时间,就遍历奇数次,想要偶时间,就经历偶数次。这样这个题目的中心要求就一目了然了,就是判断这个图中是否存在奇数的环,不过判断之前,首先确定这个图是连通的。
- 二分图的定义: 二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。
- 二分图含有的隐含特征:根据定义,你可以查看任意一个图,会发现含有奇数节点的环的图不可能为二分图,因此二分图是不含有奇数的环。
- 采用二分图染色原理判断是否含有奇数环;
-
#include<stdio.h> #include<algorithm> #include <vector> using namespace std; #include <string.h> #define maxn 100005 int n,m,s,flag,ans[maxn]; vector<int>Q[maxn]; void dfs(int x) { for(int i = 0; i<Q[x].size(); i++) { int y = Q[x][i]; if(ans[y]==-1) { ans[y] = ans[x]^1; dfs(y); } else if(ans[y]==ans[x]) { flag = 1; return ; } } return ; } int main() { int t,Case=1; scanf("%d",&t); while(t--) { scanf("%d %d %d",&n,&m,&s); for(int i=0; i<maxn-1; i++) Q[i].clear(); int x,y; int in[maxn]; memset(in,0,sizeof(in)); for(int i=0; i<m; i++) { scanf("%d %d",&x,&y); in[x]++; in[y]++; Q[x].push_back(y); Q[y].push_back(x); } int kmp = 0 ; for(int i=0; i<n; i++) if(in[i]==0) { kmp = 1; break; } printf("Case %d: ",Case++); memset(ans,-1,sizeof(ans)); flag = 0; dfs(s); if(!flag||kmp) puts("NO"); else puts("YES"); } return 0; }
简单二分图的应用
最新推荐文章于 2022-07-06 18:17:12 发布