【dfs+思维】ACM ICPC 2017–2018, NEERC – Northern Eurasia Finals Problem C. Connections

本文介绍了一个Codeforces竞赛题目,目标是在有向图中移除特定数量的边,使得图保持全连通状态。通过两次深度优先搜索算法(DFS),分别从正向和反向遍历图,找出可以安全移除的边,从而实现图的优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem C. Connections

http://codeforces.com/gym/101630

给你n个点,m条有向边,问你只保留n-2*m条边,使整个图为全连通图

请输出不要的边,special judge

DFS正着扫一遍,反着扫一遍,要是这条边都没被扫到,就可以不要了

#include <bits/stdc++.h>
using namespace std;
const int maxn=100010;
const int maxm=200010;

int n, m;

int head1[maxn], to1[maxm], from1[maxm], nxt1[maxm], tot1;
int head2[maxn], to2[maxm], from2[maxm], nxt2[maxm], tot2;
bool vis[maxn], vis1[maxn];

void addedge(int u, int v)
{
    from1[tot1] = u;
    to1[tot1] = v;
    nxt1[tot1] = head1[u];
    head1[u] = tot1++;

    from2[tot2] = v;
    to2[tot2] = u;
    nxt2[tot2] = head2[v];
    head2[v] = tot2++;
}

void dfs1(int t)
{
    for(int i = head1[t]; i != -1; i = nxt1[i])
    {
        if(!vis[to1[i]])
        {
            vis1[i] = 1;
            vis[to1[i]] = 1;
            dfs1(to1[i]);
        }
    }
}

void dfs2(int t)
{
    for(int i = head2[t]; i != -1; i = nxt2[i])
    {
        if(!vis[to2[i]])
        {
            vis1[i] = 1;
            vis[to2[i]] = 1;
            dfs2(to2[i]);
        }
    }
}




int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        memset(head1, -1, sizeof head1);
        memset(head2, -1, sizeof head2);
        memset(vis, 0, sizeof vis);
        memset(vis1, 0, sizeof vis1);
        tot1 = 0, tot2 = 0;
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= m; i++)
        {
            int u, v;
            scanf("%d%d", &u, &v);
            addedge(u - 1, v - 1);
        }
        dfs1(0);
        memset(vis, 0, sizeof vis);
        dfs2(0);
        int sum = m;
        for(int i = 0; i < m && sum != 2 * n; i++)
        {
            if(!vis1[i])
            {
                sum--;
                cout << from1[i] + 1 << " " << to1[i] + 1 <<endl;
            }
        }
    }
    return 0;
}





 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值