1. 程式人生 > >洛谷P4553 80人環遊世界

洛谷P4553 80人環遊世界

題目描述

https://www.luogu.org/problemnew/show/P4553

題解

思路比較顯然,把圖建出來,一個國家拆成兩個點,中間設定上下界,然後跑費用流。

我把源那邊的流量也設定了上下界,但是題解沒有,為什麼我按照題解的建圖方法會WA?

程式碼

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define N 209
#define inf 2e9
using namespace std;
queue<int>q;
int head[N],dis[N],tot=1,pre[N],fl[N],ans,n,m; bool vis[N]; inline int rd(){ int x=0;char c=getchar();bool f=0; while(!isdigit(c)){if(c=='-')f=1;c=getchar();} while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();} return f?-x:x; } struct edge{int n,to,l,f;}e[50003]; inline void
add(int u,int v,int l,int f){ e[++tot].n=head[u];e[tot].to=v;head[u]=tot;e[tot].l=l;e[tot].f=f; e[++tot].n=head[v];e[tot].to=u;head[v]=tot;e[tot].l=0;e[tot].f=-f; } inline bool spfa(int s,int t){ memset(dis,0x3f,sizeof(dis)); q.push(s);dis[s]=0;fl[s]=2e9; while(!q.empty()){
int u=q.front();q.pop();vis[u]=0; for(int i=head[u];i;i=e[i].n){ int v=e[i].to; if(e[i].l&&dis[v]>dis[u]+e[i].f){ dis[v]=dis[u]+e[i].f;pre[v]=i;fl[v]=min(fl[u],e[i].l); if(!vis[v]){vis[v]=1;q.push(v);} } } } return dis[t]!=0x3f3f3f3f; } inline void calc(int s,int t){ int x=t; while(x!=s){ int i=pre[x]; e[i].l-=fl[t];e[i^1].l+=fl[t];x=e[i^1].to; } ans+=dis[t]*fl[t]; } int main(){ n=rd();m=rd(); int s=2*n+3,t=2*n+4,x; for(int i=1;i<=n;++i){ x=rd();add(i,t,x,0);add(s,i+n,x,0); add(0,s,m,0);add(i+n,2*n+1,m,0); } // add(2*n+2,0,m,0); add(s,0,m,0);add(2*n+2,t,m,0); add(2*n+1,2*n+2,m,0); for(int i=1;i<=n;++i) for(int j=i+1;j<=n;++j){ x=rd();if(x>=0)add(i+n,j,m,x); } while(spfa(s,t))calc(s,t); printf("%d\n",ans); return 0; }