P2153 [SDOI2009]晨跑
阿新 • • 發佈:2018-11-11
比較顯然的拆點費用流。
按照套路,網路流跑兩個關鍵字的最優化問題時,可以把所有的第一個關鍵字都乘第二個關鍵字的和,最後計算答案時直接取膜即可。
#include<bits/stdc++.h> #define il inline #define vd void typedef long long ll; il int gi(){ int x=0,f=1; char ch=getchar(); while(!isdigit(ch)){ if(ch=='-')f=-1; ch=getchar(); } while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); return x*f; } const int maxn=403,maxm=100000; int fir[maxn],dis[maxm],nxt[maxm],w[maxm],cnt,id=1;ll cost[maxm]; il vd link(int a,int b,int c,ll d){ nxt[++id]=fir[a],fir[a]=id,dis[id]=b,w[id]=c,cost[id]=d; nxt[++id]=fir[b],fir[b]=id,dis[id]=a,w[id]=0,cost[id]=-d; } int in[201],out[201],S,T; il bool Mincost(ll&Total){ static int que[maxn],inq[maxn],lst[maxn],hd,tl; static ll dist[maxn]; for(int i=1;i<=cnt;++i)dist[i]=1000000000000000ll,lst[i]=0; hd=tl=0;que[tl++]=S;inq[S]=1; dist[S]=0; while(hd^tl){ int x=que[hd]; for(int i=fir[x];i;i=nxt[i]) if(w[i]&&dist[dis[i]]>dist[x]+cost[i]){ dist[dis[i]]=dist[x]+cost[i];lst[dis[i]]=i; if(!inq[dis[i]])inq[dis[i]]=1,que[tl++]=dis[i],tl%=maxn; } ++hd,hd%=maxn;inq[x]=0; } if(lst[T]==0)return 0; for(int i=lst[T];i;i=lst[dis[i^1]])Total+=cost[i],--w[i],++w[i^1]; return 1; } int main(){ #ifndef ONLINE_JUDGE freopen("2153.in","r",stdin); freopen("2153.out","w",stdout); #endif int n=gi(),m=gi(),a,b,c; for(int i=1;i<=n;++i)in[i]=++cnt,out[i]=++cnt; S=++cnt,T=++cnt; link(S,out[1],1e9,-1000000000000ll);link(in[n],T,1e9,0); for(int i=1;i<=n;++i)link(in[i],out[i],1,0); while(m--)a=gi(),b=gi(),c=gi(),link(out[a],in[b],1,c); ll ans=0;while(Mincost(ans)); printf("%lld %lld\n",(-ans+1000000000000ll)/1000000000000ll,ans%1000000000000ll+1000000000000ll); return 0; }