• 牛客小白月赛12 I (tarjan求割边)


    题目链接:https://ac.nowcoder.com/acm/contest/392/I

    题目大意:一个含有n个顶点m条边的图,求经过所有顶点必须要经过的边数。

    例:

    输入:

    5 5
    1 2
    2 3
    3 4
    4 5
    3 5

    输出:

    3

    解题思路:比赛的时候想的是,如果一个顶点不在环里,那与它相连的边就必定是一定要经过的边,所有可以用拓扑排序把不在环上的顶点进行统计一下,每去一个顶点必定去掉一条边,所以我们可以用总的边数减去不在环上的点的个数,不过这有个问题就是当有n个顶点,n-1条边的时候,产生的结果会是-1,开始没考虑这种情况WA了两发,我们只需要把答案和0取个最大值就好了。

    然后就是出的题解用的是tarjan,显然必要的边是割边,我们用总边数减去割边数就可以了。

    Tarjan做法:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=300005;
    int n,m,head[maxn],par[maxn],dfn[maxn],low[maxn],tot,cnt,ans;
    struct node{
        int to,next;
    }edge[2*maxn];
    void add(int u,int v){
        edge[tot].to=v;
        edge[tot].next=head[u];
        head[u]=tot++;
    }
    void Tarjan(int u){
        dfn[u]=low[u]=++cnt;
        for(int i=head[u];i!=-1;i=edge[i].next){
            int v=edge[i].to;
            if(!dfn[v]){
                par[v]=u;
                Tarjan(v);
                if(low[v]>dfn[u]) ans++;
                low[u]=min(low[u],low[v]);
            }
            else if(v!=par[u]) low[u]=min(low[u],dfn[v]);
        }
    }
    int main(){
        cin>>n>>m;
        for(int i=1;i<=n;i++)head[i]=-1;
        for(int i=1;i<=m;i++){
            int u,v;
            cin>>u>>v;
            add(u,v);
            add(v,u);
        }
        Tarjan(1);
        cout<<m-ans<<endl;
        return 0;
    }

    拓扑做法:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<string>
    #include<set>
    #include<cmath>
    #include<list>
    #include<deque>
    #include<cstdlib>
    #include<bitset>
    #include<stack>
    #include<map>
    #include<queue>
    using namespace std;
    typedef long long ll;
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    #define pushup() tree[rt]=tree[rt<<1]+tree[rt<<1|1]
    const int INF=0x3f3f3f3f;
    const double PI=acos(-1.0);
    const double eps=1e-6;
    const ll mod=10007;
    const int maxn=1000005;
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
    const int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
    int n,m,in[100005],sum;
    vector<int> mp[100005];
    void topsort(){
        queue<int> que;
        for(int i=1;i<=n;i++){
            if(in[i]==1){
                que.push(i); sum++;
            }
        }
        while(que.size()){
            int u=que.front();
            que.pop();
            int size=mp[u].size();
            for(int i=0;i<size;i++){
                int v=mp[u][i];
                in[v]--;
                if(in[v]==1){
                    que.push(v);
                    sum++;
                }
            }
        }
    }
    int main(){
        cin>>n>>m;
        for(int i=1;i<=m;i++){
            int u,v;
            scanf("%d%d",&u,&v);
            mp[u].push_back(v);
            mp[v].push_back(u);
            in[u]++; in[v]++;
        }
        topsort();
        int ans=max(m-sum,0);
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    python学习笔记(unittest)
    python学习笔记(session)
    python学习笔记(requests)
    jmeter的学习(配置环境)
    Codeforces 576D. Flights for Regular Customers 题解
    Codeforces 1316F. Battalion Strength 题解
    2020年第十一届蓝桥杯省赛J-网络分析(带权并查集)
    第十一届蓝桥杯b组省赛 C.合并检测(内附详细的样例)
    蓝桥杯2020.7月真题走方格(到达终点的不同方案数)(记忆化搜索+DP)
    Codeforces Global Round 11 A. Avoiding Zero(思维构造)
  • 原文地址:https://www.cnblogs.com/zjl192628928/p/10517787.html
Copyright © 2020-2023  润新知