bzoj1070: [SCOI2007]修车(费用流)

1070: [SCOI2007]修车

题目:传送门 

题解:

   一道挺简单的费用流吧...胡乱建模走起

贴个代码...

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 int n,m,st,ed,ans;
 8 struct node
 9 {
10     int x,y,c,d,next,other;
11 }a[210000];int len,last[1100];
12 void ins(int x,int y,int c,int d)
13 {
14     int k1,k2;
15     k1=++len;
16     a[len].x=x;a[len].y=y;a[len].c=c;a[len].d=d;
17     a[len].next=last[x];last[x]=len;
18      
19     k2=++len;
20     a[len].x=y;a[len].y=x;a[len].c=0;a[len].d=-d;
21     a[len].next=last[y];last[y]=len;
22      
23     a[k1].other=k2;
24     a[k2].other=k1;
25 }
26 int head,tail,list[110000],dis[110000],pre[110000],cc[110000];
27 bool v[110000];
28 bool spfa()
29 {
30     memset(cc,0,sizeof(cc));cc[st]=99999999;
31     memset(v,false,sizeof(v));v[st]=true;
32     memset(dis,0x3F,sizeof(dis));dis[st]=0;
33     head=1;tail=2;list[1]=st;pre[st]=0;
34     while(head!=tail)
35     {
36         int x=list[head];
37         for(int k=last[x];k;k=a[k].next)
38         {
39             int y=a[k].y;
40             if( (a[k].c>0) && (dis[y]>dis[x]+a[k].d) )
41             {
42                 cc[y]= min(cc[x],a[k].c);
43                 dis[y]=dis[x]+a[k].d;
44                 pre[y]=k;
45                 if(!v[y])
46                 {
47                     v[y]=true;
48                     list[tail++]=y;
49                     if(tail==ed+1) tail=1;
50                 }
51                   
52             }
53         }
54         v[x]=false;
55         head++; if(head==ed+1)head=1;
56     }
57     if(dis[ed]>999999999)return false;
58     ans+=dis[ed]*cc[ed];
59     int x=ed;
60     while(x!=st)
61     {
62         int k=pre[x];
63         a[k].c-=cc[ed];a[a[k].other].c+=cc[ed];
64         x=a[k].x;
65     }   
66     return true;
67 }
68 int map[1100][1100];
69 int main()
70 {
71     scanf("%d%d",&m,&n);
72     len=0;memset(last,0,sizeof(last));
73     for(int i=1;i<=n;i++)
74         for(int j=1;j<=m;j++)
75         {
76             scanf("%d",&map[i][j]);
77         }
78     st=n+m*n+1;ed=st+1;
79     for(int i=1;i<=n;i++)
80     {
81         for(int j=1;j<=m;j++)
82         {
83             for(int k=1;k<=n;k++)
84             {
85                 ins(i,j*n+k,1,map[i][j]*(n-k+1));
86             }
87         }
88     }
89     for(int i=1;i<=n;i++)ins(st,i,1,0);
90     for(int i=n+1;i<=n+n*m;i++)ins(i,ed,1,0);
91     ans=0;
92     while(spfa());
93     printf("%.2lf\n",double(ans)/n);
94     return 0;
95 }

 

posted @ 2018-02-07 11:00  CHerish_OI  阅读(174)  评论(0编辑  收藏  举报