网络流24题之汽车加油问题
唉,spfa中c写成w了改了半天。。。
首先这题可以用spfa直接模拟过
但这里我们是要做网络流的,所以我们还是按照分层图建网络流
对于一个状态d[i][j]表示走到i时还能走j步,然后我们把这个状态看成一个点做就行了
By:大奕哥
顺便祝各位长沙旅行愉快
1 #include<iostream> 2 #include<cstdlib> 3 #include<cstdio> 4 #include<algorithm> 5 #include<cstring> 6 #include<queue> 7 #include<vector> 8 #include<cmath> 9 using namespace std; 10 const int N=1e6+10; 11 inline int read(){ 12 int x=0,f=1;char ch=getchar(); 13 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 14 while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+ch-'0',ch=getchar(); 15 return x*f; 16 } 17 int head[N],base=10000,d[N],f[N],p[505][505],cnt=-1,num,n,k,A,B,C,cost,s,t; 18 bool v[N]; 19 struct node{ 20 int to,nex,w,c,f; 21 }e[10000005]; 22 void add(int x,int y,int w,int c) 23 { 24 // cout<<x<<" "<<y<<" "<<w<<" "<<c<<endl; 25 e[++cnt].to=y;e[cnt].nex=head[x];head[x]=cnt;e[cnt].w=w;e[cnt].f=x;e[cnt].c=c; 26 e[++cnt].to=x;e[cnt].nex=head[y];head[y]=cnt;e[cnt].w=0;e[cnt].f=y;e[cnt].c=-c; 27 } 28 queue<int>q; 29 bool spfa() 30 { 31 memset(v,0,sizeof(v)); 32 memset(f,-1,sizeof(f)); 33 memset(d,0x3f,sizeof(d)); 34 d[s]=0;v[s]=1;q.push(s); 35 while(!q.empty()) 36 { 37 int x=q.front();q.pop();v[x]=0; 38 for(int i=head[x];i!=-1;i=e[i].nex) 39 { 40 int y=e[i].to; 41 if(d[y]<d[x]+e[i].c||!e[i].w)continue; 42 f[y]=i;d[y]=d[x]+e[i].c; 43 if(!v[y])v[y]=1,q.push(y); 44 } 45 } 46 if(d[t]>1e9)return 0; 47 int flow=1e9; 48 for(int i=f[t];i!=-1;i=f[e[i].f]) 49 flow=min(flow,e[i].w); 50 for(int i=f[t];i!=-1;i=f[e[i].f]) 51 e[i].w-=flow,e[i^1].w+=flow,cost+=flow*e[i].c; 52 return 1; 53 } 54 int main() 55 { 56 // freopen("1.out","r",stdin); 57 // freopen("my.out","w",stdout); 58 n=read();k=read();A=read();B=read();C=read(); 59 memset(head,-1,sizeof(head)); 60 for(int i=1;i<=n;++i) 61 for(int j=1;j<=n;++j) 62 p[i][j]=++num; 63 s=0;t=n*n+base*k+10; 64 add(s,p[1][1]+base*k,1,0); 65 for(int i=0;i<=k;++i) 66 add(p[n][n]+base*i,t,1,0); 67 for(int i=1;i<=n;++i) 68 for(int j=1;j<=n;++j) 69 { 70 int x;x=read(); 71 if(!x) 72 { 73 for(int q=0;q<k;++q)add(p[i][j]+base*q,p[i][j]+base*k,1,A+C); 74 for(int q=1;q<=k;++q) 75 { 76 if(i+1<=n)add(p[i][j]+base*q,p[i+1][j]+base*(q-1),1,0); 77 if(j+1<=n)add(p[i][j]+base*q,p[i][j+1]+base*(q-1),1,0); 78 if(i-1)add(p[i][j]+base*q,p[i-1][j]+base*(q-1),1,B); 79 if(j-1)add(p[i][j]+base*q,p[i][j-1]+base*(q-1),1,B); 80 } 81 } 82 else 83 { 84 for(int q=0;q<k;++q) 85 { 86 if(i+1<=n)add(p[i][j]+base*q,p[i+1][j]+base*(k-1),1,A); 87 if(j+1<=n)add(p[i][j]+base*q,p[i][j+1]+base*(k-1),1,A); 88 if(i-1)add(p[i][j]+base*q,p[i-1][j]+base*(k-1),1,A+B); 89 if(j-1)add(p[i][j]+base*q,p[i][j-1]+base*(k-1),1,A+B); 90 } 91 } 92 } 93 while(spfa()); 94 printf("%d",cost); 95 return 0; 96 }
生命中真正重要的不是你遭遇了什么,而是你记住了哪些事,又是如何铭记的。