zoukankan      html  css  js  c++  java
  • poj2987 求最大权闭合回路

    建图差不多和以前做的差不多,就是最后询问这个闭合子图有多少个的时候,只要输出这个图的S集合,就是进行dfs能遍历到的点一定在S集合中,不能遍历到的点在T集合中

    #include <iostream>
    #include <algorithm>
    #include <string.h>
    #include <cstdio>
    #include <vector>
    #include <queue>
    using namespace std;
    const int maxn=5555;
    const long long INF=1LL<<60;
    typedef long long LL;
    struct Dinic
    {
    
        struct Edge{
          LL from,to,cap,flow;
          Edge(LL cfrom=0,LL cto=0,LL ccap=0,LL cflow=0)
          {
              from=cfrom;  to=cto; cap=ccap; flow=cflow;
          }
        };
        int n,m,s,t;
        vector<Edge>edges;
        vector<int>G[maxn];
        bool vis[maxn];
        int d[maxn];
        int cur[maxn];
        void init(int n)
        {
            m=0;
            this->n=n;
            for(int i=0; i<=n; i++)G[i].clear();
            edges.clear();
        }
        void addEdge(LL from,LL to, LL cap)
        {
            edges.push_back(Edge(from,to,cap,0) );
            edges.push_back(Edge(to,from,0,0));
            m+=2;
            G[from].push_back(m-2);
            G[to].push_back(m-1);
        }
        bool BFS()
        {
            memset(vis,0,sizeof(vis));
            queue<int>Q;
           Q.push(s);
          d[s]=0;
          vis[s]=1;
          while(!Q.empty())
            {
                int x=Q.front(); Q.pop();
                for(int i=0; i<G[x].size(); i++)
                {
                    Edge &e = edges[G[x][i]];
                    if(vis[e.to]==false&&e.cap>e.flow)
                    {
                         vis[e.to]=1;
                         d[e.to]=d[x]+1;
                         Q.push(e.to);
                    }
                }
            }
            return vis[t];
        }
        LL DFS(int x,LL a)
        {
            if(x==t||a==0)return a;
            LL flow=0,f;
            for(int &i=cur[x]; i<G[x].size(); i++)
            {
                Edge &e=edges[G[x][i]];
                LL  dd =min(a,e.cap-e.flow);
                if(d[x]+1==d[e.to]&&(f=DFS(e.to,dd))>0)
                {
                    e.flow+=f;
                    edges[G[x][i]^1].flow-=f;
                    flow+=f;
                    a-=f;
                    if(a==0)break;
                }
            }
            return flow;
        }
        LL Maxflow(int s,int t)
        {
            this->s=s;this->t=t;
            LL flow=0;
            while(BFS())
            {
                memset(cur,0,sizeof(cur));
                flow+=DFS(s,INF);
            }
            return flow;
        }
        void find(int cur)
        {
            vis[cur]=true;
            for(int i=0; i<G[cur].size(); i++)
            {
                Edge &e=edges[G[cur][i]];
                if(vis[e.to]||e.cap<=e.flow)continue;
                find(e.to);
            }
        }
        int solve()
        {
            memset(vis,0,sizeof(vis));
            for(int i=0; i<G[s].size(); i++)
            {
                Edge &e=edges[G[s][i]];
                if(vis[e.to]||e.cap<=e.flow)continue;
                find(e.to);
            }
            int ans=0;
            for(int i=1; i<=n-2; i++)
                ans+=vis[i];
            return ans;
        }
    }T;
    int P[maxn];
    int main()
    {
         int n,m;
         while(scanf("%d%d",&n,&m)==2)
         {
             LL S1=0,S2=0;
             T.init(n+2);
             for(int i=1; i<=n; i++)
             {
                 scanf("%d",&P[i]);
                 if(P[i]>0){
                    S1+=P[i];S2+=P[i];
                    T.addEdge(n+1,i,P[i]);
                 }else{
                    S1+=-P[i];
                    T.addEdge(i,n+2,-P[i]);
                 }
             }
             for(int i=1; i<=m; i++)
             {
                 int a,b;
                 scanf("%d%d",&a,&b);
                 T.addEdge(a,b,S1);
             }
             LL a1=T.Maxflow(n+1,n+2);
             LL a2=T.solve();
             printf("%I64d %I64d
    ",a2,S2-a1);
         }
         return 0;
    }
    View Code
  • 相关阅读:
    C#多线程学习笔记(三)——线程池
    html解析工具
    怎么样获取手机的主题
    我改进的《豆瓣搜》前后对比及源代码
    【收藏】Silverlight Style (二) 自定义样式在后台代码中应用
    C#多线程学习笔记(一)
    学习Linux——学习正确的思考方式(转)
    电信禁路由上网的破解方法
    印度软件业
    中国与印度软件工程师之比较
  • 原文地址:https://www.cnblogs.com/Opaser/p/4918912.html
Copyright © 2011-2022 走看看