混合图
文件名dizzy.c/cpp/pas 时间限制1s 内存限制128M
题目描述
YZM有一张N个点,M1条有向边,M2条无向边组成的混合图。询问一个给所有无向边定向的方案。使得最终的图中没有环。保证一定有解。
输入格式(输入文件dizzy.in)
第一行,三个数字N,M1,M2。
接下来M1+M2行,每行两数字Ai,Bi。表示一条边。
前M1条是有向边。方向是Ai到Bi。
输出格式(输出文件dizzy.out)
输出M2行,按输出顺序输出为无向边确定的方向。Ai Bi或BiAi。
无解只输出“-1”。
样例数据
Input
4 2 3
1 2
4 3
1 3
4 2
3 2
Output
1 3
2 4
2 3
数据规模
1<=N<=100 0001<=M1,M2<=100 000
----------------------------------------------------------------------------
如果本身是有向图是一个环,直接输出-1。
以为如果有环,即出现了反向的道路,这时想到了拓扑序,对于无向边,将其从拓扑序小的连到大的。显然不会出现环
#include <cstdio> #include <queue> #include <cstring> #include <algorithm> using namespace std; const int N=1e5+7; int head[N],tp[N],dee[N],ru[N]; int n,m1,m2,cnt,num; struct edge { int t,next; }e[N]; void add(int u,int t) { e[++cnt].t=t; e[cnt].next=head[u]; head[u]=cnt; } queue<int> q; void Tup() { for (int i=1;i<=n;i++) { if (!ru[i]) q.push(i); } while (!q.empty()) { int u=q.front();q.pop(); tp[++num]=u; for (int i=head[u];i!=-1;i=e[i].next) { int v=e[i].t; ru[v]--;dee[v]=max(dee[v],dee[u]+1); if (!ru[v]) q.push(v); } } } int main() { freopen("dizzy.in","r",stdin); freopen("dizzy.out","w",stdout); scanf("%d%d%d",&n,&m1,&m2); memset(head,-1,sizeof head); for (int i=1,u,v;i<=m1;i++) { scanf("%d%d",&u,&v); add(u,v);ru[v]++; } Tup(); if (num!=n) { puts("-1"); return 0; } for (int i=1;i<=n;i++) { dee[tp[i]]=i; } for (int i=1;i<=m2;i++) { int u,v; scanf("%d%d",&u,&v); if (dee[u]>dee[v]) swap(u,v); printf("%d %d\n",u,v); } }