您的位置:首页 > 其它

Connections Gym - 101630C DFS/有向图的强联通分量边集

2017-12-12 22:07 429 查看
题目链接

求有向图强连通分量的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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: