zoukankan      html  css  js  c++  java
  • poj 1637 Sightseeing tour——最大流+欧拉回路

    题目:http://poj.org/problem?id=1637

    先给无向边随便定向,如果一个点的入度大于出度,就从源点向它连 ( 入度 - 出度 / 2 ) 容量的边,意为需要流出去这么多;流出去1表示改了一条边的方向,会使自己出度-1、入度+1,所以容量要/2;出度大于入度的点类似地连向汇点;无向边按给它定的方向的反方向连上容量为1的边;最后看看能否满流即可。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int N=205,M=1005,INF=N*M;
    int n,m,deg[N],hd[N],xnt,cur[N],sm[N],gn[N],gt[N],dfn[N];
    struct Ed{
      int to,nxt,cap;
      Ed(int a=0,int b=0,int c=0):to(a),nxt(b),cap(c) {}
    }ed[M+N<<1];
    queue<int> q;
    int rdn()
    {
      int ret=0;bool fx=1;char ch=getchar();
      while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}
      while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();
      return fx?ret:-ret;
    }
    void init()
    {
      xnt=1;memset(deg,0,sizeof deg);//xnt=1!!!
      memset(sm,0,sizeof sm);memset(hd,0,sizeof hd);
      memset(gn,0,sizeof gn);memset(gt,0,sizeof gt);
    }
    void add(int x,int y,int z)
    {
      ed[++xnt]=Ed(y,hd[x],z);hd[x]=xnt;
      ed[++xnt]=Ed(x,hd[y],0);hd[y]=xnt;
    }
    bool bfs()
    {
      memset(dfn,0,sizeof dfn);
      dfn[0]=1;q.push(0);
      while(q.size())
        {
          int k=q.front();q.pop();
          for(int i=hd[k],v;i;i=ed[i].nxt)
        if(!dfn[v=ed[i].to]&&ed[i].cap)
          dfn[v]=dfn[k]+1,q.push(v);
        }
      return dfn[n+1];
    }
    int dinic(int cr,int flow)
    {
      if(cr==n+1)return flow;//
      int use=0;
      for(int& i=cur[cr],v;i;i=ed[i].nxt)
        if(dfn[v=ed[i].to]==dfn[cr]+1&&ed[i].cap)
          {
        int tmp=dinic(v,min(flow-use,ed[i].cap));
        if(!tmp)dfn[v]=n+2;
        use+=tmp;ed[i].cap-=tmp;ed[i^1].cap+=tmp;
        if(use==flow)return use;
          }
      return use;
    }
    int main()
    {
      int T=rdn();
      while(T--)
        {
          n=rdn();m=rdn();init();
          for(int i=1,u,v,fx;i<=m;i++)
        {
          u=rdn();v=rdn();fx=rdn();
          deg[u]++;deg[v]++;sm[v]++;sm[u]--;//in - out
          if(!fx)add(v,u,1);
          else gn[v]++,gt[u]++;
        }
          bool flag=0;int val=0;
          for(int i=1;i<=n;i++)
        {
          if((deg[i]&1)||gn[i]>(deg[i]>>1)||gt[i]>(deg[i]>>1))
            {flag=1;break;}
          if(sm[i]>0)add(0,i,sm[i]>>1),val+=sm[i]>>1;
          else if(sm[i]<0)add(i,n+1,-sm[i]>>1);
        }
          if(flag){puts("impossible");continue;}
          int mxflow=0;
          while(bfs())
        {memcpy(cur,hd,sizeof hd);mxflow+=dinic(0,INF);}//fr:0 !!!
          if(mxflow==val)puts("possible");
          else puts("impossible");
        }
      return 0;
    }
  • 相关阅读:
    poj----1330Nearest Common Ancestors(简单LCA)
    Tarjan--LCA算法的个人理解即模板
    hdu----(4545)魔法串(LCS)
    hdu---(1325)Is It A Tree?(并查集)
    hdu----(1599)最大子矩阵(几何/dp)
    hdu---(1054)Strategic Game(最小覆盖边)
    整理的一些模版LCS(连续和非连续)
    hdu---(4310)Hero(贪心算法)
    hdu----(4308)Saving Princess claire_(搜索)
    hdu------(4302)Holedox Eating(树状数组+二分)
  • 原文地址:https://www.cnblogs.com/Narh/p/10117837.html
Copyright © 2011-2022 走看看