P2017 [USACO09DEC]暈牛Dizzy Cows
阿新 • • 發佈:2018-10-16
void int front degree 定向 ret ans top 可能
圖論日常不會系列。。。
題意:給定有向邊和無向邊,然後給每一條無向邊定向,使得到的圖無環。
我本來想縮一下點的,但是越想越暈。
然後就翻了題解,恍然大悟。。。
其實只需要給只有有向邊的圖跑一次toposort。然後把無向邊的定向看做是在添加有向邊。
顯然不要違反拓撲序來添加有向邊,這個圖就不可能有環!
所以隨便搞一搞就好了。。。
代碼:
#include<cstdio> #include<queue> const int maxn = 100005; struct Edges { int next, to; } e[maxn * 3]; int head[maxn], tot; int indegree[maxn]; int topo[maxn], ttot; int where[maxn]; struct Query { int u, v; } Q[maxn]; int n, m1, m2; int read() { int ans = 0, s = 1; char ch = getchar(); while(ch > ‘9‘ || ch < ‘0‘){ if(ch == ‘-‘) s = -1; ch = getchar(); } while(ch >= ‘0‘ && ch <= ‘9‘) ans = (ans << 3) + (ans << 1) + ch - ‘0‘, ch = getchar(); return s * ans; } void link(int u, int v) { e[++tot] = (Edges){head[u], v}; head[u] = tot; } void toposort() { std::queue<int> q; for(int i = 1; i <= n; i++) if(indegree[i] == 0) q.push(i); while(!q.empty()) { int u = q.front(); q.pop(); topo[++ttot] = u; for(int i = head[u]; i; i = e[i].next) { int v = e[i].to; indegree[v]--; if(indegree[v] == 0) { q.push(v); } } } } int main() { n = read(), m1 = read(), m2 = read(); while(m1--) { int u = read(), v = read(); link(u, v); indegree[v]++; } for(int i = 1; i <= m2; i++) { Q[i].u = read(), Q[i].v = read(); } toposort(); for(int i = 1; i <= ttot; i++) where[topo[i]] = i; for(int i = 1; i <= m2; i++) { int temp1 = where[Q[i].u], temp2 = where[Q[i].v]; if(temp1 < temp2) printf("%d %d\n", Q[i].u, Q[i].v); else printf("%d %d\n", Q[i].v, Q[i].u); } return 0; }
P2017 [USACO09DEC]暈牛Dizzy Cows