zoukankan      html  css  js  c++  java
  • POJ1637_Sightseeing tour

    给一个联通图,有的是单向边,有的是双向边,问是否存在欧拉回路。

    乍一看毫无思路,可以这样来搞,对于每条无向边,我们随便指定一个方向,看看是否能够做到所有点的度数之和为偶数。

    接下来,对于我们指定的边,假设指定的是U->V,那么我们也同时在网络中设置一条同样的边,使得流量为1,最后如果某点的出入度只差不为0,那么我们把那个差除以2,这表示我们在这个点处至少需要改变多少条无向边的方向。对于出大于入的点,我们连源点,对于入大于出的点,我们连汇点,最后跑最大流看看所有的与源点和汇点的边能否满流即可。

    一开始的想法是,不指定方向,直接跑最大流,这样是错的,因为无法保证每条无向边最终都被指定了方向,也就是对应回题目里面,不一定无向边都遍历到了,而通过首先指定一个方向,然后再改变方向的方法可以保证这一点。

     

     

    召唤代码君:

     

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #define maxn 2220
    #define maxm 22220
    using namespace std;
    
    int to[maxm],next[maxm],first[maxn],c[maxm],edge;
    int d[maxn],tag[maxn],can[maxn],dgr[maxn],TAG=520;
    int n,m,T,s,t,sum,ans;
    int Q[maxn],bot,top;
    const int inf=~0U>>1;
    
    void _init()
    {
        sum=ans=s=0,t=n+1,edge=-1;
        for (int i=s; i<=t; i++) first[i]=-1,dgr[i]=0;
    }
    
    bool check()
    {
        for (int i=1; i<=n; i++)
            if (dgr[i]&1) return false;
        return true;
    }
    
    void addedge(int U,int V,int W)
    {
        edge++;
        to[edge]=V,c[edge]=W,next[edge]=first[U],first[U]=edge;
        edge++;
        to[edge]=U,c[edge]=0,next[edge]=first[V],first[V]=edge;
    }
    
    bool bfs()
    {
        Q[bot=top=1]=t,d[t]=0,tag[t]=++TAG;
        while (bot<=top)
        {
            int cur=Q[bot++];
            for (int i=first[cur]; i!=-1; i=next[i])
                if (c[i^1]>0 && tag[to[i]]!=TAG)
                {
                    tag[to[i]]=TAG,d[to[i]]=d[cur]+1;
                    can[to[i]]=false,Q[++top]=to[i];
                    if (to[i]==s) return true;
                }
        }
        return false;
    }
    
    int dfs(int cur,int num)
    {
        if (cur==t) return num;
        int tmp=num,k;
        for (int i=first[cur]; i!=-1; i=next[i])
            if (c[i]>0 && tag[to[i]]==TAG && d[to[i]]==d[cur]-1 && !can[to[i]])
            {
                k=dfs(to[i],min(num,c[i]));
                if (k) num-=k,c[i]-=k,c[i^1]+=k;
                if (num==0) break;
            }
        if (num>0) can[cur]=true;
        return tmp-num;
    }
    
    int main()
    {
        int U,V,W;
        scanf("%d",&T);
        while (T--)
        {
            scanf("%d%d",&n,&m);
            _init();
            while (m--)
            {
                scanf("%d%d%d",&U,&V,&W);
                dgr[U]--,dgr[V]++;
                if (W==0) addedge(U,V,1);
            }
            if (!check())
            {
                puts("impossible");
                continue;
            }
            for (int i=1; i<=n; i++)
            {
                if (dgr[i]==0) continue;
                if (dgr[i]<0) addedge(s,i,-dgr[i]/2);
                else
                {
                    sum+=dgr[i]/2;
                    addedge(i,t,dgr[i]/2);
                }
            }
            while (bfs()) ans+=dfs(s,inf);
            if (ans==sum) puts("possible");
                else puts("impossible");
        }
        return 0;
    }
    如有转载,请注明出处(http://www.cnblogs.com/lochan)
  • 相关阅读:
    java fastjson 设置全局输出name最小化
    Spring MVC同一方法返回JSON/XML格式
    使用Vuejs编写单js组件
    iview使用vue-i18n实现国际化
    WPF usercontrol 自定义依赖属性
    正在尝试解析依赖项“MvvmLightLibs (≥ 5.2.0.0)”。 “MvvmLightLibs”已拥有为“CommonServiceLocator”定义的依赖项
    记第一次的破解经历
    HTML5实现手机QQ表情功能
    TypeScript 基本语法
    WebStorm下使用TypeScript
  • 原文地址:https://www.cnblogs.com/lochan/p/3854836.html
Copyright © 2011-2022 走看看