Connections Gym

来源:互联网 发布:免费chinanet软件2017 编辑:程序博客网 时间:2024/06/06 01:03

题目链接

求有向图强连通分量的2n个边的边集首先从1开始DFS可以走到的所有点,并记录走过的边这样就满足了从1可达所有其他点然后从1开始DFS走反向边,这样保证其他点可达1点.两遍dfs       
#include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn = 1e5+5;struct node{    int to;    int ind;};int u[maxn];int v[maxn];int ans[maxn];vector<node> G[maxn];vector<node> G1[maxn];int T;int n,m;int vis[maxn];void dfs(int cur){    vis[cur]=1;    for(int i=0;i<G[cur].size();i++)    {        if(vis[G[cur][i].to ]) continue;        ans[ G[cur][i].ind ] = 1;        dfs(G[cur][i].to );    }}void dfs1(int cur){    vis[cur]=1;    for(int i=0;i<G1[cur].size();i++)    {        if(vis[G1[cur][i].to ]) continue;        ans[ G1[cur][i].ind ] = 1;        dfs1(G1[cur][i].to );    }}int main(){//    freopen("data.txt","r",stdin);//    ios_base::sync_with_stdio(false);//    cin >> T;    scanf("%d",&T);    while(T--)    {        memset(ans,0,sizeof(ans));        memset(vis,0,sizeof(vis));        scanf("%d %d",&n,&m);        for(int i=0;i<=n;i++)        {            G[i].clear();        }        for(int i=0;i<=n;i++)        {            G1[i].clear();        }        node nt;        for(int i=1;i<=m;i++)        {            scanf("%d %d",&u[i],&v[i]);            nt.to = v[i];            nt.ind = i;            G[u[i]].push_back(nt);            nt.to = u[i];            nt.ind = i;            G1[v[i]].push_back(nt);        }        dfs(1);        memset(vis,0,sizeof(vis));        dfs1(1);        int ct = m-2*n;        for(int i=1;i<=m&&ct;i++)        {            if(!ans[i])            {                ct--;                printf("%d %d\n",u[i],v[i]);            }        }    }    return 0;}
原创粉丝点击