1. 程式人生 > >BZOJ 1631: [Usaco2007 Feb]Cow Party

BZOJ 1631: [Usaco2007 Feb]Cow Party

用邊建正反倆張圖
然後拍spfa計算兩張圖從x點出發的最短路。。
然後掃一遍計算答案
像我這樣把兩張圖連起來跑一次spfa也行

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define ll long long
#define g getchar()
#define inf 0x3f3f3f3f
#define rep(i,n) for(int i=1;i<=n;++i)
using namespace std;
inline ll read(){
    ll x=0
,f=1;char ch=g; for(;ch<'0'||ch>'9';ch=g)if(ch=='-')f=-1; for(;ch>='0'&&ch<='9';ch=g)x=x*10+ch-'0'; return x*f; } inline void out(ll x){ int a[25],t=0; if(x<0)putchar('-'),x=-x; for(;x;x/=10)a[++t]=x%10; for(int i=t;i;--i)putchar('0'+a[i]); if(t==0)putchar
('0'); putchar('\n'); } struct re{int v,w,next;}ed[200005]; int dis[2005],pd[2005],dui[200005],head[2005],n,m,T,e,ans; inline void ins(int x,int y,int w){ed[++e]=(re){y,w,head[x]};head[x]=e;} void spfa(int S){ memset(dis,inf,sizeof(dis)); memset(pd,0,sizeof(pd)); dis[S]=0;dui[1]=S;int tou=1,wei=1; for
(;tou<=wei;pd[dui[tou++]]=0){ int u=dui[tou]; for(int i=head[u];i;i=ed[i].next){ int v=ed[i].v; if(dis[v]>dis[u]+ed[i].w){ dis[v]=dis[u]+ed[i].w; if(!pd[v])dui[++wei]=v,pd[v]=1; } } } } int main(){ // freopen("","r",stdin); // freopen("","w",stdout); n=read(),m=read(),T=read(); rep(i,m){ int x=read(),y=read(),w=read(); ins(x,y,w); ins(y+n,x+n,w); } ins(T,T+n,0); spfa(T); rep(i,n){ ans=max(dis[i]+dis[i+n],ans); } out(ans); return 0; }