1. 程式人生 > >Gym-101630C:Connections(生成樹&構造)

Gym-101630C:Connections(生成樹&構造)

int conn namespace std size long long 生成 class ons

題意:給定N點,M條有向邊,滿足任意點可以到達任意點。現在叫你保留2*N邊,任然滿足任意點可以到達任意點,輸出刪除的邊。

思路:從1出發,DFS,得到一顆生成樹,有N-1條邊。反向建題。還是從1出發,得到一顆生成樹,這2N-2條邊顯然可以滿足任意點互通。然後隨便選兩邊即可。 (任意點u->v,至少有u->1->v滿足。

#include<bits/stdc++.h>
#define pii pair<int,int>
#define ll long long
const int maxn=200010;
using namespace std;
int u[maxn],v[maxn],vis1[maxn],vis2[maxn],N; vector<int>G1[maxn],G2[maxn]; map<pii,int>mp; void dfs1(int u) { vis1[u]=1; int L=G1[u].size(); for(int i=0;i<L;i++) if(!vis1[G1[u][i]]) mp[make_pair(u,G1[u][i])]=1,dfs1(G1[u][i]); } void dfs2(int u) { vis2[u]=1; int L=G2[u].size();
for(int i=0;i<L;i++) if(!vis2[G2[u][i]]) mp[make_pair(G2[u][i],u)]=1,dfs2(G2[u][i]); } int main() { int T,M,i,j; scanf("%d",&T); while(T--){ scanf("%d%d",&N,&M); mp.clear(); memset(vis1,0,sizeof(vis1)); memset(vis2,0,sizeof(vis2)); for(i=1;i<=N;i++) G1[i].clear(),G2[i].clear();
for(i=1;i<=M;i++){ scanf("%d%d",&u[i],&v[i]); G1[u[i]].push_back(v[i]); G2[v[i]].push_back(u[i]); } dfs1(1); dfs2(1); int cnt=M-N-N; for(i=1;i<=M&&cnt;i++){ if(!mp[make_pair(u[i],v[i])]) printf("%d %d\n",u[i],v[i]),cnt--; } } return 0; }

Gym-101630C:Connections(生成樹&構造)