【BZOJ】【1927】【SDOI2010】星际竞速
2015-03-18 17:49
239 查看
网络流/费用流
比较简单的一题,对于每个星球,将它拆成两个点,然后二分图建模:左部结点与S相连,流量为1费用为0;右部结点与T相连,流量为1费用为0;对于每条航道x->y,连边x->y+n,流量为1,费用为w[i]。那么瞬移到某个星球呢?直接连S->n+i,容量为1费用为a[i]。
(建图描述的已经比较清晰了,我就不给大家配图了,自己手画一下就行,很简单的)
因为是最大流,所以每个星球一定都经过了(每个右部结点都流过了),而每个星球都是从花费最少的那条路径过来的!
这题由于每个星球都必须经过,且有瞬移的存在,所以其实就是一个贪心,找出到达每个点的最小代价即可(这里的到达就走一步……比如星球4可以从星球2过来,那么就光考虑瞬移a[4]和由2过来的航道w[i]这两个权值即可)
/************************************************************** Problem: 1927 User: Tunix Language: C++ Result: Accepted Time:3148 ms Memory:5988 kb ****************************************************************/ //BZOJ 1927 #include<vector> #include<cstdio> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define rep(i,n) for(int i=0;i<n;++i) #define F(i,j,n) for(int i=j;i<=n;++i) #define D(i,j,n) for(int i=j;i>=n;--i) #define pb push_back using namespace std; inline int getint(){ int v=0,sign=1; char ch=getchar(); while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();} while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();} return v*sign; } const int N=1610,M=200000,INF=~0u>>2; typedef long long LL; /******************tamplate*********************/ int a ,n,m,ans; struct edge{int from,to,v,c;}; struct Net{ edge E[M]; int head ,next[M],cnt; void ins(int x,int y,int z,int c){ E[++cnt]=(edge){x,y,z,c}; next[cnt]=head[x]; head[x]=cnt; } void add(int x,int y,int z,int c){ ins(x,y,z,c); ins(y,x,0,-c); } int from ,Q[M],d ,S,T; bool inq ,sign; bool spfa(){ int l=0,r=-1; F(i,1,T) d[i]=INF; d[S]=0; Q[++r]=S; inq[S]=1; while(l<=r){ int x=Q[l++]; inq[x]=0; for(int i=head[x];i;i=next[i]) if(E[i].v>0 && d[x]+E[i].c<d[E[i].to]){ d[E[i].to]=d[x]+E[i].c; from[E[i].to]=i; if (!inq[E[i].to]){ Q[++r]=E[i].to; inq[E[i].to]=1; } } } return d[T]!=INF; } void mcf(){ int x=INF; for(int i=from[T];i;i=from[E[i].from]) x=min(x,E[i].v); for(int i=from[T];i;i=from[E[i].from]){ E[i].v-=x; E[i^1].v+=x; } ans+=x*d[T]; } void init(){ n=getint(); m=getint(); cnt=1; S=0; T=n*2+1; F(i,1,n){ a[i]=getint(); add(S,n+i,1,a[i]); add(S,i,1,0); add(n+i,T,1,0); } int x,y,z; F(i,1,m){ x=getint(); y=getint(); z=getint(); if (x>y) swap(x,y); add(x,y+n,1,z); } while(spfa()) mcf(); printf("%d\n",ans); } }G1; int main(){ #ifndef ONLINE_JUDGE freopen("1927.in","r",stdin); freopen("1927.out","w",stdout); #endif G1.init(); return 0; }
View Code
相关文章推荐
- 【费用流】BZOJ1927-[Sdoi2010]星际竞速
- bzoj 1927: [Sdoi2010]星际竞速
- bzoj1927: [Sdoi2010]星际竞速
- 【bzoj】1927 [Sdoi2010]星际竞速
- BZOJ1927: [Sdoi2010]星际竞速
- BZOJ1927 [Sdoi2010]星际竞速
- [bzoj1927] [Sdoi2010]星际竞速
- BZOJ1927 [Sdoi2010]星际竞速
- [bzoj1927][Sdoi2010]星际竞速
- bzoj 1927 [Sdoi2010]星际竞速
- [bzoj1927][SDOI2010]星际竞速
- 【bzoj1927】[Sdoi2010]星际竞速
- bzoj1927 [Sdoi2010]星际竞速
- BZOJ1927 [SDOI2010] 星际竞速
- bzoj1927[Sdoi2010]星际竞速
- bzoj1927 [Sdoi2010]星际竞速
- bzoj1927 [Sdoi2010]星际竞速
- BZOJ1927: [Sdoi2010]星际竞速
- BZOJ1927 [Sdoi2010]星际竞速 【费用流】
- bzoj1927 [Sdoi2010]星际竞速