poj 2987 Firing ------最大权闭合图

来源:互联网 发布:.net 465端口发邮件 编辑:程序博客网 时间:2024/05/22 07:37

网络流里的最大权闭合图和最大密度子图还是挺有意思的

方法:s连接正权点,点权赋给边,t连接负权点,点权的绝对值赋给边,原图两点之间的边用inf64正向容量连接,逆向为0.

这样就能把每一个最小割和每一个闭合图一一对应,利用最小割的性质很好证明。然后求出最小割,用所有正权和减去得到最大获利。因为最小割把图分成了两部分,所以最后求最小人数可以用一个贪心,方法是从s出发广度优先搜索,能达到的节点都是需要开除的,这样就能统计出最大获利时的最小人数!

#include<iostream>#include<vector>#include<algorithm>#include<cstdio>#include<queue>#include<stack>#include<string>#include<map>#include<set>#include<cmath>#include<cassert>#include<cstring>#include<iomanip>using namespace std;#ifdef _WIN32#define i64 __int64#define out64 "%I64d\n"#define in64 "%I64d"#else#define i64 long long#define out64 "%lld\n"#define in64 "%lld"#endif#define FOR(i,a,b)      for( int i = (a) ; i <= (b) ; i ++)#define FF(i,a)         for( int i = 0 ; i < (a) ; i ++)#define FFD(i,a)        for( int i = (a)-1 ; i >= 0 ; i --)#define S64(a)          scanf(in64,&a)#define SS(a)           scanf("%d",&a)#define LL(a)           ((a)<<1)#define RR(a)           (((a)<<1)+1)#define SZ(a)           ((int)a.size())#define PP(n,m,a)puts("---");FF(i,n){FF(j,m)cout << a[i][j] << ' ';puts("");}#define pb              push_back#define CL(Q)           while(!Q.empty())Q.pop()#define MM(name,what)   memset(name,what,sizeof(name))#define read            freopen("in.txt","r",stdin)#define write           freopen("out.txt","w",stdout)const int inf = 0x3f3f3f3f;const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL;const double oo = 10e9;const double eps = 10e-8;const double pi = acos(-1.0);const int maxn=5011;const int end=5001;struct zz{    int from;    int to;    i64 c;    int id;}zx,tz;int n,m,tx,ty;i64 pro,total;int cost[maxn];vector<zz>g[maxn];queue<int>q;int cen[maxn];bool vis[maxn];bool bfs(){    CL(q);    MM(cen,-1);     q.push(0);    cen[0] = 0;    int now,to;    while(!q.empty())    {        now = q.front();        q.pop();        FF(i,g[now].size())        {            to = g[now][i].to;            if(cen[to] == -1 && g[now][i].c > 0)            {                cen[to] = cen[now] + 1;                q.push(to);            }        }     }    return cen[end] != -1;         }i64 dfs(i64 flow = inf , int now = 0 ){    if(now == end)    {        return flow;    }                       i64 temp,sum=0;    int to;    FF(i,g[now].size())    {        to = g[now][i].to;        if (g[now][i].c > 0 && flow > sum && cen[to] == cen[now] + 1 )         {            temp = dfs ( min ( flow - sum , g[now][i].c ) , to );            sum += temp;                g[now][i].c -= temp;            g[to][g[now][i].id].c += temp;                   }    }                                                if(!sum) cen[now] = -1;    return sum;}void dinic(){    i64 ans = 0;    while(bfs())    {        ans += dfs();    }    pro = total - ans;      return ;}void bfs2(){    int ans = 0;    CL(q);      MM(vis,false);    vis[0] = true;    q.push(0);    int now,to;    while(!q.empty())    {        now = q.front();        q.pop();        FF(i,g[now].size())        {            to = g[now][i].to;            if(g[now][i].c > 0 && !vis[to] )            {                vis[to] = true;                 ans++;                q.push(to);                            }        }         }    cout<<ans<<" ";    return ;}           int main(){    total = 0;     cin>>n>>m;    FOR(i,1,n)    {        SS(cost[i]);        if(cost[i] > 0)        {            total += cost[i];        }    }        FOR(i,1,m)    {        SS(tx);        SS(ty);        zx.from = tx;        zx.to = ty;        zx.c = inf64;        zx.id = g[ty].size();        g[tx].pb(zx);        swap(zx.from,zx.to);            zx.c = 0;        zx.id = g[tx].size() - 1;         g[zx.from].pb(zx);    }    FOR(i,1,n)    {        if(cost[i]>0)        {            zx.from = 0;            zx.to = i;             zx.c = cost[i];            zx.id = g[i].size();            g[0].pb(zx);            swap(zx.from,zx.to);            zx.c = 0;            zx.id = g[0].size()-1;              g[i].pb(zx);                 }            else if(cost[i]<0)        {            zx.from = i;            zx.to = end;            zx.c = -cost[i];             zx.id = g[end].size();            g[i].pb(zx);                swap(zx.from,zx.to);            zx.c = 0;            zx.id = g[i].size() - 1;            g[end].pb(zx);        }      }    dinic();    bfs2();      cout<<pro<<endl;    return 0;   }


原创粉丝点击