其他分享
首页 > 其他分享> > G - Railway HDU - 3394(点双连通分量)

G - Railway HDU - 3394(点双连通分量)

作者:互联网

There are some locations in a park, and some of them are connected by roads. The park manger needs to build some railways along the roads, and he would like to arrange tourist routes to each circuit. If a railway belongs to more than one tourist routes, there might be clash on it, and if a railway belongs to none tourist route, it doesn’t need to build. 
Now we know the plan, and can you tell us how many railways are no need to build and how many railways where clash might happen.

Input

The Input consists of multiple test cases. The first line of each test case contains two integers, n (0 < n <= 10000), m (0 <= m <= 100000), which are the number of locations and the number of the railways. The next m lines, each line contains two integers, u, v (0 <= u, v < n), which means the manger plans to build a railway on the road between u and v. 
You can assume that there is no loop and no multiple edges. 
The last test case is followed by two zeros on a single line, which means the end of the input.

Output

Output the number of railways that are no need to build, and the number of railways where clash might happen. Please follow the format as the sample.

Sample Input

8 10
0 1
1 2
2 3
3 0
3 4
4 5
5 6
6 7
7 4
5 7
0 0

Sample Output

1 5

题目大意:给出n个点m条边的无向图简单图(无环无重边),每一个环会安排一条旅游路线,如果一条边不属于任何路线(环),就认为是没有必要的;如果一条边属于多条旅游路线,则认为是会冲突的;求出没必要的边和冲突边数

 

题解:

代码:还是应该加强一下点双和边双的求法以及和割点割边之间的联系

//#include<bits/stdc++.h>
#include<iostream>
#include<queue>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<map>
#include<stack>
#include<vector>
#define rep(i,e) for(int i=0;i<(e);++i)
#define rep1(i,e) for(int i=1;i<=(e);++i)
#define repx(i,x,e) for(int i=(x);i<=(e);++i)
#define pii pair<int,int>
#define X first
#define Y second
#define PB push_back
#define MP make_pair
#define mset(var,val) memset(var,val,sizeof(var))
#define scd(a) scanf("%d",&a)
#define scdd(a,b) scanf("%d%d",&a,&b)
#define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define IOS ios::sync_with_stdio(false);cin.tie(0)

using namespace std;

#ifdef LOCAL
template<typename T>
void dbg(T t){
    cout<<t<<" "<<endl;
}
template<typename T, typename... Args>
void dbg(T t, Args... args){
    cout<<t<<" ";dbg(args...);
}


#else
#define dbg(...)
#endif // local
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3fll;
const int mod = 1e9+7;
const int N = 500+10;
typedef long long ll;
const int maxn = 1e4+10;
const int maxm =1e5+10;

struct node{
    int u,v,next;
}edge[maxm*2];
int head[maxn],low[maxn],dfn[maxn],dfn_cnt,bccno[maxn],bcc_cnt;
int cnt,iscut[maxm*2],cut_cnt;
bool vis[maxn];
int bcce[maxn];
stack<pii>S;
vector<int>B[maxn];
void add(int u,int v)
{
    edge[++cnt].v = v;
    edge[cnt].u = u;
    edge[cnt].next = head[u];
    head[u] = cnt;
}

void tarjan(int u,int fa)
{
    low[u] = dfn[u] = ++dfn_cnt;
    for(int i = head[u]; ~i; i = edge[i].next)
    {
        int v = edge[i].v;
        pii p = MP(u,v);
        if(!dfn[v])
        {
            S.push(p);
            tarjan(v,u);
            low[u] = min(low[u],low[v]);
            if(low[v] > dfn[u])
                cut_cnt++;
            if(low[v] >= dfn[u])
            {
                bcc_cnt++;
                B[bcc_cnt].clear();
                for(;;){
                    bcce[bcc_cnt]++;
                    pii tmp = S.top();S.pop();
                    if(bccno[tmp.X] != bcc_cnt) B[bcc_cnt].PB(tmp.X),bccno[tmp.X] = bcc_cnt;
                    if(bccno[tmp.Y] != bcc_cnt) B[bcc_cnt].PB(tmp.Y),bccno[tmp.Y] = bcc_cnt;
                    if(tmp.X == u && tmp.Y == v) break;
                }
            }
        }else if(dfn[v] < dfn[u] && v != fa)
        {
            S.push(p);
            low[u] = min(low[u],dfn[v]);
        }
    }
}


void work()
{
    int n,m,x,y;
    while(cin>>n>>m)
    {
        for(int i = 0; i <= n; i++)
        {
            head[i] = -1;
            low[i] = dfn[i] = bccno[i] = vis[i] = bcce[i]  = 0;
        }
        bcc_cnt = cut_cnt = 0;
        cnt = 1;
        dfn_cnt = 0;
        memset(iscut,0,sizeof(iscut));
        if(n == m && n == 0) break;
        for(int i = 0; i < m; i++)
        {
            cin>>x>>y;
            add(x,y);
            add(y,x);
        }
        for(int i = 0; i < n; i++)
        {
            if(!dfn[i])
                tarjan(i,-1);
        }
        cout<<cut_cnt<<" ";
        int res = 0;
        for(int i = 1; i <= bcc_cnt; i++)
        {
            if(bcce[i] > B[i].size())
                res += bcce[i];
        }
        cout<<res<<endl;
    }
}

int main()
{
#ifdef LOCAL
    freopen("in.txt","r",stdin);
#endif
    IOS;
    work();
    return 0;
}

 

标签:tmp,HDU,点双,int,cnt,3394,dfn,include,define
来源: https://blog.csdn.net/scau_cdx/article/details/89786950