题意:
输入一张有向图,无自回路和重边,判断能否将它变为有向图,使得图中任意一条路径长度都小于2。
如果可以,按照输入的边的顺序输出构造的每条边的方向,构造的边与输入的方向一致就输出1,否则输出0。
题解:
当我看到“图中任意一条路径长度都小于2”这句话的时候我都懵了,不知道这道题让干啥的。
最后没想到就是句面意思,因为题目中给你了m条无向边,每条无向边长度都是1,那么所有路径长度都小于2,就要这样做:
比如无向图边为:
1 2
2 3
3 4
那么变成有向图就要
1->2
2<-3
3->4
即,这条边的方向要与上一条边相反
那么这个时候我们就可以用DFS染色判断二分图的方法来处理这道题。
染色过程中的处理:
1、不能出现奇环(DFS染色判断二分图不可能出现奇环,因为如果出现奇环,那么它就肯定不是一个二分图,因为如果出现奇环那么同样的颜色的点之间也会连线)
由上图可知,偶环可满足题意。
观察这个图你会发现有一句话很适合它:“构造的有向图中,对于每个顶点,要么所有边都是出,要么所有边都是入。”
那么就可以把它转变成两个颜色0,1染色,0代表所有以该点为起点的边变成有向边时,方向要改变。1代表所有以该点为起点的边变成有向边时,方向不改变。
代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<iostream> 4 #include<algorithm> 5 #include<math.h> 6 #include<vector> 7 #include<queue> 8 #include<stack> 9 #include<map> 10 using namespace std; 11 typedef long long ll; 12 const int maxn=2e5+10; 13 const int INF=0x3f3f3f3f; 14 const double eps=1e-10; 15 const int mod = 1e9+7; 16 #define mt(A,B) memset(A,B,sizeof(A)) 17 #define lson l,m,rt*2 18 #define rson m+1,r,rt*2+1 19 #define SIS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) 20 map<string,int> r; 21 vector<int> g[maxn], a; //a是输入的第i条边的起点 22 bool vis[maxn]; 23 int c[maxn]; //第i个点的颜色 24 bool isok = true; 25 26 void dfs(int x, int cur) { //第x个点,涂cur颜色 27 vis[x] = true; 28 c[x] = cur; 29 for(int i = 0; i < g[x].size(); i++) { 30 if(vis[g[x][i]]) { 31 if(c[x] == c[g[x][i]]) 32 isok = false; 33 else 34 continue; 35 } 36 else { 37 if(cur == 0) 38 dfs(g[x][i], 1); 39 else 40 dfs(g[x][i], 0); 41 } 42 } 43 } 44 45 int main() { 46 // freopen("in.txt", "r", stdin); 47 // freopen("out.txt", "w", stdout); 48 int n, m, x, y; 49 scanf("%d%d", &n, &m); 50 for(int i = 1; i <= m; i++) { 51 scanf("%d%d", &x, &y); 52 g[x].push_back(y); 53 g[y].push_back(x); 54 a.push_back(x); 55 } 56 dfs(1, 0); 57 if(!isok) 58 printf("NO\n"); 59 else { 60 printf("YES\n"); 61 for(int i = 0; i < a.size(); i++) { 62 printf("%d", c[a[i]]); 63 } 64 } 65 return 0; 66 }
哪有错误的话@我一下^_^