原来URAL中tricky problem都是这么得微妙……
直接将原图遍历,然后按遍历的时间将边标号即可,对于任意一个点,如果有至少两条边和其相连,那么至少有两条边的访问顺序是连续的,那么由于相邻的两个数的最大公约数是1,于是这样遍历一定能够得到解。
#include<stdio.h> #include<string.h> #define MAXD 60 #define MAXM 2510 int N, M, e, first[MAXD], next[MAXM], v[MAXM], flag[MAXM], cnt; void add(int x, int y) { v[e] = y, flag[e] = 0; next[e] = first[x], first[x] = e ++; } void init() { int i, x, y; e = 0; memset(first, -1, sizeof(first)); for(i = 0; i < M; i ++) { scanf("%d%d", &x, &y); add(x, y), add(y, x); } } void dfs(int cur) { int i; for(i = first[cur]; i != -1; i = next[i]) if(!flag[i]) { flag[i] = flag[i ^ 1] = ++ cnt; dfs(v[i]); } } void solve() { int i, j, k; cnt = 0; for(i = 1; i <= N; i ++) dfs(i); printf("YES\n"); printf("%d", flag[0]); for(i = 1; i < M; i ++) printf(" %d", flag[i << 1]); printf("\n"); } int main() { while(scanf("%d%d", &N, &M) == 2) { init(); solve(); } return 0; }