zoukankan      html  css  js  c++  java
  • 混合欧拉回路poj 1637 Sightseeing tour

    把该图的无向边随便定向,计算每个点的入度和出度。如果有某个点出入度之差为奇数,那么肯定不存在欧拉回路。因为欧拉回路要求每点入度 = 出度,也就是总度数为偶数,存在奇数度点必不能有欧拉回路;

    好了,现在每个点入度和出度之差均为偶数。那么将这个偶数除以2,得x。也就是说,对于每一个点,只要将x条边改变方向(入>出就是变入,出>入就是变出),就能保证出=入。如果每个点都是出=入,那么很明显,该图就存在欧拉回路。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int M=205;
    const int inf=0x3f3f3f3f;
    inline int read(){
        int sum=0,x=1;
        char ch=getchar();
        while(ch<'0'||ch>'9'){
            if(ch=='-')
                x=0;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
            sum=(sum<<1)+(sum<<3)+(ch^48),ch=getchar();
        return x?sum:-sum;
    }
    inline void write(int x){
        if(x<0)
            putchar('-'),x=-x;
        if(x>9)
            write(x/10);
        putchar(x%10+'0');
    }
    struct node{
        int v,w,nextt;
    }e[2005];
    int deep[M],cur[M],head[M],du[M],tot,s,t;
    bool bfs(){
        for(int i=0;i<=t;i++)
            deep[i]=0;
        queue<int>que;
        que.push(s);
        deep[s]=1;
        while(!que.empty()){
            int u=que.front();
            que.pop();
            for(int i=head[u];~i;i=e[i].nextt){
                int v=e[i].v;
                if(e[i].w>0&&deep[v]==0){
                    deep[v]=deep[u]+1;
                    if(v==t){
                        return true;
                    }
                    que.push(v);
                }
            }
        }
        return deep[t]==0?false:true;
    }
    int dfs(int u,int fl){
        if(u==t){
            return fl;
        }
        int x,ans=0;
        for(int i=cur[u];~i;i=e[i].nextt){
            int v=e[i].v;
            if(e[i].w>0&&deep[v]==deep[u]+1){
                x=dfs(v,min(fl-ans,e[i].w));
                e[i].w-=x;
                e[i^1].w+=x;
                if(e[i].w)
                    cur[u]=i;
                ans+=x;
                if(ans==fl)
                    return ans;
            }
        }
        if(ans==0)
            deep[u]=0;
        return ans;
    }
    int dinic(){
        int ans=0;
        while(bfs()){
            //cout<<ans<<endl;
            for(int i=0;i<=t;i++)
                cur[i]=head[i];
            ans+=dfs(s,inf);
        }
        return ans;
    }
    void addedge(int u,int v,int w){
        e[tot].v=v;
        e[tot].w=w;
        e[tot].nextt=head[u];
        head[u]=tot++;
        e[tot].v=u;
        e[tot].w=0;
        e[tot].nextt=head[v];
        head[v]=tot++;
    }
    void init(){
        for(int i=0;i<=t;i++)
            head[i]=-1,du[i]=0;
        tot=0;
    }
    int main(){
        int p=read();
    
        while(p--){
            int n=read(),m=read();
            s=0,t=n+1;
            init();
            while(m--){
                int u=read(),v=read(),op=read();
                du[u]++,du[v]--;
                if(!op)
                    addedge(u,v,1);
            }
            //jud
            int flag=0;
            for(int i=1;i<=n;i++){
                if(du[i]&1){
                    flag=1;
                    break;
                }
            }
            if(flag){
                puts("impossible");
                continue;
            }
            int sum=0;
            for(int i=1;i<=n;i++){
                if(du[i]<0)
                    addedge(i,t,-du[i]/2);
                else if(du[i]>0)
                    addedge(s,i,du[i]/2),sum+=du[i]/2;
            }
            if(sum!=dinic())
                puts("impossible");
            else
                puts("possible");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    大整数模拟
    MSSQL存储过程中获取记录集并循环操作一例
    about协议的妙用
    C#基础概念二十五问
    很完美的JS判断日期函数
    asp.net C# FileUpload 控件如何判断文件名的后缀
    c++中指针学习的两个绝好例子
    ASP.net性能优化总结
    C++指针
    JS中的undefined,null,"",0和false
  • 原文地址:https://www.cnblogs.com/starve/p/10939563.html
Copyright © 2011-2022 走看看