网络流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 }

 

posted @ 2018-02-03 14:36  大奕哥&VANE  阅读(206)  评论(0编辑  收藏  举报