bzoj 2055 80人环游地球(上下界费用流)

来源:互联网 发布:请叫我威廉三世知轩 编辑:程序博客网 时间:2024/05/11 03:39
/**************************************************************    Problem: 2055    User: Clare    Language: C++    Result: Accepted    Time:560 ms    Memory:2140 kb****************************************************************/ #include <cstdio>#include <iostream>#include <algorithm>#include <cstring>#include <cmath>#include <queue>#include <vector>using namespace std; #define N 210#define INF 0x3f3f3f3f int n,m,SS,S,T;struct Edge{    int next,value,to,cost,from;}edge[N*N];int head[N],tot=1;int pre[N],dis[N],in[N];long long Ans;bool exist[N];queue<int> Q; inline int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}    return x*f;} void Addedge(int u,int v,int w,int c){    tot++;edge[tot].next=head[u];edge[tot].from=u;edge[tot].to=v;    edge[tot].value=w;edge[tot].cost=c;head[u]=tot;    tot++;edge[tot].next=head[v];edge[tot].from=v;edge[tot].to=u;    edge[tot].value=0;edge[tot].cost=-c;head[v]=tot;} bool SPFA(){    memset(dis,INF,sizeof(dis));    memset(exist,0,sizeof(exist));    dis[S]=0;exist[S]=true;    Q.push(S);    while(!Q.empty())    {        int now=Q.front();Q.pop();        exist[now]=false;        for(int i=head[now];i;i=edge[i].next)        {            int v=edge[i].to;            if(edge[i].value>0&&dis[v]>dis[now]+edge[i].cost)            {                dis[v]=dis[now]+edge[i].cost;                pre[v]=i;                if(!exist[v])                {                    exist[v]=true;                    Q.push(v);                }            }        }    }    if(dis[T]!=INF)        return true;    else return false;} void DFS(){    int qwer=INF;    for(int i=pre[T];i;i=pre[edge[i].from])        qwer=min(qwer,edge[i].value);    for(int i=pre[T];i;i=pre[edge[i].from])    {        edge[i].value-=qwer;        edge[i^1].value+=qwer;        Ans+=(long long)qwer*edge[i].cost;    }} int main(){    n=read();m=read();    S=0;SS=2*n+1;T=2*n+2;    for(int i=1;i<=n;i++)    {        int x=read();        Addedge(i,i+n,0,0);        in[i]-=x;in[i+n]+=x;    }    Addedge(S,SS,m,0);    for(int i=1;i<=n;i++)        Addedge(SS,i,INF,0);    for(int i=1;i<=n;i++)    {        for(int j=i+1;j<=n;j++)        {            int x=read();            if(x==-1)                continue;            Addedge(i+n,j,INF,x);        }    }    for(int i=1;i<=2*n;i++)    {        if(in[i]>0)            Addedge(S,i,in[i],0);        else Addedge(i,T,-in[i],0);    }    while(SPFA())        DFS();    cout<<Ans<<endl;    return 0;}

0 0