版权声明:本文为博主原创文章,喜欢就点个赞吧 https://blog.csdn.net/Anxdada/article/details/82026887
传送门
题意: 给定一个无向图, 然后你要给这幅图每条边加上一个方向, 使得这个图是有向图强连通
思路: 关键在于如何判断无解的情况, 如果能保证当前的图有解, 那么直接dfs一下就可以出答案. 仔细想想知道. 其实就是判断一下当前这幅图是否有”桥” , 联通分量的定义的桥, 如果有桥则一定无解, 否则就有解, 然后dfs一下就可以得到答案了. 细节请看代码
AC Code
const int maxn = 1e6+5;
int dfn[maxn], low[maxn];
int dfs_id, bri_num;
int n, m;
int cnt , head[maxn];
void init() {
Fill(dfn, 0); Fill(low, 0);
cnt = 2; Fill(head, -1);
dfs_id = bri_num = 0;
}
struct node {
int to, next;
}e[maxn<<1];
void add(int u, int v) {
e[cnt] = node{v, head[u]};
head[u] = cnt++;
}
void Findbri(int u, int fa) {
dfn[u] = low[u] = ++dfs_id;
for(int i = head[u] ; ~i ; i = e[i].next) {
int v = e[i].to;
if((i^1) == fa) continue;
if(!dfn[v]) {
Findbri(v, i);
low[u] = min(low[u], low[v]);
if(low[v] > dfn[u]) bri_num++;
}
else low[u] = min(low[u], dfn[v]);
}
}
int ans[maxn], vis[maxn];
void dfs(int u, int fa) {
vis[u] = 1;
for(int i = head[u] ; ~i ; i = e[i].next) {
int to = e[i].to;
ans[i/2] = (i&1) ? 0 : 1;
if (to == fa || vis[to]) continue;
dfs(to, u);
}
}
void solve() {
scanf("%d%d", &n, &m);
init();
for (int i = 1 ; i <= m ; i ++) {
int u, v;
scanf("%d%d", &u, &v);
add(u, v); add(v, u);
}
for (int i = 1 ; i <= n ; i ++) {
if (!dfn[i]) Findbri(i, -1);
}
if (bri_num) {
puts("impossible");
return ;
}
for (int i = 1 ; i <= n ; i ++) {
if (!vis[i]) dfs(i, -1);
}
for (int i = 1 ; i <= m ; i ++) {
printf("%d", ans[i]);
}
printf("\n");
}