您的位置:首页 > 运维架构

BZOJ1738: [Usaco2005 mar]Ombrophobic Bovines 发抖的牛

2017-09-14 19:10 387 查看

n<=200个点m<=1500条无向带权边的图,每个点有人和容量,人可以移动,代价为所有人走过的边的权和,求使所有点人不超过容量的最小代价。

方法一:费用流。

错误!答案与边权不成比例。

方法二:二分一个答案,然后根据floyd求出的最短路看每个点在二分的答案下能去到哪些点,跑最大流检查是否合法。

1 #include<stdio.h>
2 #include<string.h>
3 #include<stdlib.h>
4 #include<algorithm>
5 //#include<iostream>
6 using namespace std;
7
8 int n,m;
9 #define maxn 411
10 #define maxm 100011
11 #define LL long long
12 int a[maxn],b[maxn],sum=0;
13 LL mp[maxn][maxn];
14 const LL inf=1e15;
15 struct Edge{int from,to,next,cap,flow;};
16 struct Network
17 {
18     Edge edge[maxm];int n,s,t,le;
19     int first[maxn],dis[maxn],cur[maxn];
20     void clear(int n)
21     {
22         memset(first,0,sizeof(first));
23         le=2;this->n=n;
24     }
25     void add_edge(int x,int y,int v)
26     {
27         Edge &e=edge[le];
28         e.to=y;e.from=x;
29         e.cap=v;e.flow=0;
30         e.next=first[x];
31         first[x]=le++;
32     }
33     void insert(int x,int y,int v)
34     {
35         add_edge(x,y,v);
36         add_edge(y,x,0);
37     }
38     int que[maxn],head,tail;
39     bool bfs()
40     {
41         memset(dis,0,sizeof(dis));
42         dis[s]=1;
43         que[head=(tail=1)-1]=s;
44         while (head!=tail)
45         {
46             const int x=que[head++];
47             for (int i=first[x];i;i=edge[i].next)
48             {
49                 Edge &e=edge[i];
50                 if (e.cap>e.flow && !dis[e.to])
51                 {
52                     dis[e.to]=dis[x]+1;
53                     que[tail++]=e.to;
54                 }
55             }
56         }
57         return dis[t];
58     }
59     int dfs(int x,int a)
60     {
61         if (x==t || !a) return a;
62         int flow=0,f;
63         for (int &i=cur[x];i;i=edge[i].next)
64         {
65             Edge &e=edge[i];
66             if (dis[e.to]==dis[x]+1 && (f=dfs(e.to,min(a,e.cap-e.flow)))>0)
67             {
68                 flow+=f;
69                 a-=f;
70                 e.flow+=f;
71                 edge[i^1].flow-=f;
72                 if (!a) break;
73             }
74         }
75         return flow;
76     }
77     int Dinic(int s,int t)
78     {
79         this->s=s;this->t=t;
80         int ans=0;
81         while (bfs())
82         {
83             for (int i=1;i<=n;i++) cur[i]=first[i];
84             ans+=dfs(s,0x3f3f3f3f);
85         }
86         return ans;
87     }
88 }g;
89 bool check(LL x)
90 {
91     g.clear(n*2+2);
92     int s=g.n-1,t=g.n;
93     for (int i=1;i<=n;i++)
94     {
95         g.insert(s,i,a[i]);
96         g.insert(i+n,t,b[i]);
97     }
98     for (int i=1;i<=n;i++)
99         for (int j=1;j<=n;j++)
100             if (mp[i][j]<=x) g.insert(i,j+n,0x3f3f3f3f);
101     return g.Dinic(s,t)==sum;
102 }
103 int x,y,v;
104 int main()
105 {
106     scanf("%d%d",&n,&m);
107     for (int i=1;i<=n;i++)
108         scanf("%d%d",&a[i],&b[i]),sum+=a[i];
109     for (int i=1;i<=n;i++)
110         for (int j=1;j<=n;j++)
111             mp[i][j]=inf;
112     for (int i=1;i<=n;i++) mp[i][i]=0;
113     for (int i=1;i<=m;i++)
114     {
115         scanf("%d%d%d",&x,&y,&v);
116         mp[x][y]=min(mp[x][y],(LL)v);
117         mp[y][x]=min(mp[y][x],(LL)v);
118     }
119     for (int k=1;k<=n;k++)
120         for (int i=1;i<=n;i++)
121             for (int j=1;j<=n;j++)
122                 if (mp[i][j]>mp[i][k]+mp[k][j])
123                     mp[i][j]=mp[i][k]+mp[k][j];
124     LL L=0,R=1e15;
125     while (L<R)
126     {
127         const LL mid=(L+R)>>1;
128         if (check(mid)) R=mid;
129         else L=mid+1;
130     }
131     printf(R==1e15?"-1\n":"%lld\n",L);
132     return 0;
133 }
View Code

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: