码迷,mamicode.com
首页 > 其他好文 > 详细

Battle (hdu 3061 最大权闭合图模板题)

时间:2015-05-03 09:22:25      阅读:200      评论:0      收藏:0      [点我收藏+]

标签:battle   hdu 3061   最大权闭合图模板题   

Battle

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 963    Accepted Submission(s): 463


Problem Description
由于小白同学近期习武十分刻苦,很快被晋升为天策军的统帅。而他上任的第一天,就面对了一场极其困难的战斗:
据侦查兵回报,前方共有N座城池,考虑到地势原因,最终得到一个结论:攻占某些城池之前必须攻占另外一些城池。
事实上,可以把地图看做是一张拓扑图,而攻占某个城池,就意味着必须先攻占它的所有前驱结点。
小白还做了一份调查,得到了攻占每个城池会对他的兵力产生多少消耗(当然也可能会得到增长,因为每攻占一个城池,便可以整顿军队,扩充兵力,天策军的兵力十分庞大,如果不考虑收益,他们可以攻取所有的城池)。
现在请你帮小白统帅做一份战斗计划,挑选攻打哪些城市,使得天策军在战斗过后军容最为壮大。
 

Input
首先输入一个N 代表有N个城池(1<= n <= 500)
接着输入一个M,代表城池和城池之间的拓扑关系数。
接着输入N个数字 代表从1 到 N 编号城池的战斗消耗(负数代表将要消耗天策军兵力,正数表示天策军可以获得相应的战斗收益)
最后M行 每行2个数字 a,b,代表相应城池的编号。
表示攻占b之后才可以攻占a;
 

Output
天策军最大能获得多少战斗收益
 

Sample Input
5 5 8 -8 -10 12 -10 1 2 2 5 1 4 3 4 4 5
 

Sample Output
2
 

Source
 

Recommend
lcy   |   We have carefully selected several similar problems for you:  3046 1565 1569 1733 1853 


代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define maxn 1005
#define MAXN 300005
#define mod 1000000009
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-6
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define FRE(i,a,b)  for(i = a; i <= b; i++)
#define FREE(i,a,b) for(i = a; i >= b; i--)
#define FRL(i,a,b)  for(i = a; i < b; i++)
#define FRLL(i,a,b) for(i = a; i > b; i--)
#define mem(t, v)   memset ((t) , v, sizeof(t))
#define sf(n)       scanf("%d", &n)
#define sff(a,b)    scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pf          printf
#define DBG         pf("Hi\n")
typedef long long ll;
using namespace std;

struct Edge
{
    int u,v,cap,next;
}edge[MAXN];

int head[maxn],cur[maxn],level[maxn];
int n,m,num;

void init()
{
    num=0;
    mem(head,-1);
}

void addedge(int u,int v,int w)
{
    edge[num].u=u; edge[num].v=v; edge[num].cap=w; edge[num].next=head[u]; head[u]=num++;
    edge[num].u=v; edge[num].v=u; edge[num].cap=0; edge[num].next=head[v]; head[v]=num++;
}

bool bfs(int s,int t)
{
    mem(level,-1);
    queue<int>Q;
    level[s]=0;
    Q.push(s);
    while (!Q.empty())
    {
        int u=Q.front(); Q.pop();
        for (int i=head[u];i+1;i=edge[i].next)
        {
            int v=edge[i].v;
            if (level[v]==-1&&edge[i].cap>0)
            {
                level[v]=level[u]+1;
                Q.push(v);
            }
        }
    }
    return level[t]!=-1;
}

int dfs(int u,int t,int f)
{
    if (u==t) return f;
    for (int &i=cur[u];i+1;i=edge[i].next)
    {
        int v=edge[i].v;
        if (edge[i].cap>0&&level[v]==level[u]+1)
        {
            int d=dfs(v,t,min(f,edge[i].cap));
            if (d>0)
            {
                edge[i].cap-=d;
                edge[i^1].cap+=d;
                return d;
            }
        }
    }
    return 0;
}

int dinic(int s,int t,int nodenum)
{
    int flow=0,f;
    while (bfs(s,t))
    {
        for (int i=0;i<=nodenum;i++) cur[i]=head[i];
        while ((f=dfs(s,t,INF))>0)
            flow+=f;
    }
    return flow;
}

int main()
{
//    freopen("C:/Users/asus1/Desktop/IN.txt","r",stdin);
    int i,j,x,u,v;
    while (~scanf("%d%d",&n,&m))
    {
        init();
        int all=0;
        for (i=1;i<=n;i++)
        {
            scanf("%d",&x);
            if (x>0) addedge(0,i,x),all+=x;
            else addedge(i,n+1,-x);
        }
        for (i=1;i<=m;i++)
        {
            scanf("%d%d",&u,&v);
            addedge(u,v,INF);
        }
        printf("%d\n",all-dinic(0,n+1,n+2));
    }
    return 0;
}


Battle (hdu 3061 最大权闭合图模板题)

标签:battle   hdu 3061   最大权闭合图模板题   

原文地址:http://blog.csdn.net/u014422052/article/details/45442997

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!