• 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;
    }
  • 相关阅读:
    机器学习python实战----决策树
    机器学习python实战----手写数字识别
    机器学习python实战----k近邻算法
    斯坦福2014机器学习笔记八----机器学习系统的设计
    斯坦福2014机器学习笔记七----应用机器学习的建议
    斯坦福2014机器学习笔记六----神经网络(二)
    Global Game Jam 2019 深圳站 个人总结
    加法乘法线段树模板
    线段树模板题
    单调栈和单调队列入门
  • 原文地址:https://www.cnblogs.com/Narh/p/10117837.html
Copyright © 2020-2023  润新知