图论- hdu5215 Cycle

来源:互联网 发布:网络计划图关键线路 编辑:程序博客网 时间:2024/05/29 20:01

题目:

http://acm.hdu.edu.cn/showproblem.php?pid=5215

题意:

给一个无向图,无自环,无重边,问图中是否存在边数为奇数与偶数的环

思路:

二分图染色可以解决奇环,但偶环没办法直接处理

考虑到所有的环都出现在双连通子图中,用tarjan算法找出图中所有的桥,删掉

再对每个双连通子图单独染色,若在一个子图中出现了两个以上的奇环,则该图必然存在偶环


如上图,若a+b+c为一个奇环,c+d+e为另一个奇环,则a+b+d+e=(a+b+c)+(c+d+e)-c*2=奇数+奇数-偶数=偶数,必然为一个偶环


代码:

#include <stdio.h>#include <iostream>#include <string.h>#include <vector>#include <queue>#include <stack>#include <map>#include <algorithm>#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;const int maxsize=100000+5;struct node{    int u,father;};vector<int> adjList[maxsize];int dfn[maxsize],low[maxsize];int color[maxsize];bool isOdd,isEven;int sum,odd;queue<node> q;int index;void tarjan(int u,int father){    dfn[u]=low[u]=++index;    for (vector<int>::iterator it=adjList[u].begin();it!=adjList[u].end();++it){        int v=*it;        if (!dfn[v]){            tarjan(v,u);            low[u]=min(low[u],low[v]);            if (dfn[u]<low[v]){                *it=0;                for (vector<int>::iterator itv=adjList[v].begin();itv!=adjList[v].end();++itv)                    if (*itv == u) {*itv=0;break;}            }        }        else if (father!=v) {            low[u]=min(low[u],dfn[v]);        }    }    return;}void colorate(node t){    color[t.u]=1;    q.push(t);    sum++;    while (!q.empty()){        node x=q.front();        q.pop();        //  cout<<"col:"<<"u color "<<x.u<<" "<<color[x.u]<<" father: "<<x.father<<" size: "<<adjList[x.u].size()<<endl;        for (vector<int>::iterator it=adjList[x.u].begin();it!=adjList[x.u].end();++it){            int v=*it;            //cout<<v<<" "<<color[v]<<endl;            if ( v==0 || v==x.father) continue;            for (vector<int>::iterator itv=adjList[v].begin();itv!=adjList[v].end();++itv)                if (*itv == x.u) {*itv=0;break;}            if (color[v]==0){                color[v]=3-color[x.u];                q.push({v,x.u});                sum++;            }            else if (color[v]==3-color[x.u]){                isEven=true;            }            else if (color[v]=color[x.u]){                isOdd=true;                odd++;                if (odd>1) isEven=true;            }        }    }    return ;}int main(){    int total;    cin>>total;    while (total--){        int n,m;        cin>>n>>m;        for (int i=1;i<=n;++i) adjList[i].clear();        for (int i=1;i<=m;++i){            int a,b;            scanf("%d %d",&a,&b);            adjList[a].push_back(b);            adjList[b].push_back(a);        }        memset(dfn,0,sizeof(dfn));        memset(low,0,sizeof(low));        index=0;        tarjan(1,0);//        for (int i=1;i<=n;++i){//            cout<<i<<": ";//            for (int j=0;j<adjList[i].size();++j){//                cout<<adjList[i][j]<<" ";//            }//            cout<<endl;//        }        memset(color,0,sizeof(color));        //1,2;        isOdd=false;isEven=false;        sum=0;        while (sum<n){            for (int i=1;i<=n;++i){                if (color[i]==0){                    odd=0;                    colorate({i,0});                }            }        }        if (isOdd) cout<<"YES"<<endl;        else cout<<"NO"<<endl;        if (isEven) cout<<"YES"<<endl;        else cout<<"NO"<<endl;    }    return 0;}


0 0
原创粉丝点击