D. Coloring Edges
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
You are given a directed graph with n vertices and m directed edges without self-loops or multiple edges.
Let’s denote the k-coloring of a digraph as following: you color each edge in one of k colors. The k-coloring is good if and only if there no cycle formed by edges of same color.
Find a good k-coloring of given digraph with minimum possible k.
Input
The first line contains two integers n and m (2≤n≤5000, 1≤m≤5000) — the number of vertices and edges in the digraph, respectively.
Next m lines contain description of edges — one per line. Each edge is a pair of integers u and v (1≤u,v≤n, u≠v) — there is directed edge from u to v in the graph.
It is guaranteed that each ordered pair (u,v) appears in the list of edges at most once.
Output
In the first line print single integer k — the number of used colors in a good k-coloring of given graph.
In the second line print m integers c1,c2,…,cm (1≤ci≤k), where ci is a color of the i-th edge (in order as they are given in the input).
If there are multiple answers print any of them (you still have to minimize k).
Examples
inputCopy
4 5
1 2
1 3
3 4
2 4
1 4
outputCopy
1
1 1 1 1 1
inputCopy
3 3
1 2
2 3
3 1
outputCopy
2
1 1 2
题意: 一个有相图,给每条边上色,使得每个环中颜色不同。
思路: 通过画图可知(画了N个图发现),在一张连通图中,最多只有两种颜色。(我也不知道为啥,画着画着就出来了。)
然后就可以通过拓扑排序判环来判断,只要发现当前边的点被遍历过,那么当前边标记为2,其他边全为1即可。
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 100010;
struct Edge
{
int v,next;
int flag;
Edge(){
flag = 1;
}
}e[MAXN];
int head[MAXN],cnt;
bool vis[MAXN],flag;
bool viss[MAXN];
void addedge(int u, int v)
{
e[cnt].v = v;
e[cnt].next = head[u];
head[u] = cnt++;
}
void DFS(int x)
{
viss[x] = vis[x] = true;
for(int i = head[x]; ~i; i = e[i].next){
int v = e[i].v;
if(!viss[v]) DFS(v);
else if(vis[v]) { e[i].flag = 2; flag = true; continue ; }
}
vis[x] = false; //若没有发现环,则需要回溯标记false。否则在下一条链中可能会被判断为环
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
memset(head,-1,sizeof(head));
memset(vis,false,sizeof(vis));
flag = false;
for(int i = 1; i <= m; ++i){
int u,v;
scanf("%d%d",&u,&v);
addedge(u,v);
}
for(int i = 1; i <= n; ++i){
if(!viss[i]) DFS(i);
}
if(flag) printf("2\n");
else printf("1\n");
for(int i = 0; i < cnt; ++i) printf("%d ",e[i].flag);
printf("\n");
return 0;
}