3511: 土地划分
Time Limit: 10 Sec Memory Limit: 256 MB
Submit: 255 Solved: 146
[Submit][Status][Discuss]
Description
Y国有N座城市,并且有M条双向公路将这些城市连接起来,并且任意两个城市至少有一条路径可以互达。
Y国的国王去世之后,他的两个儿子A和B都想成为新的国王,但他们都想让这个国家更加安定,不会用武力解决问题。
于是他们想将这个国家分成两个小国家A国和B国。现在,A拥有1号城市,B拥有N号城市,其他的城市还尚未确定归属哪边(划分之后的国家内部城市可以不连通)。
由于大家都想让国家变得更好,而某些城市的人民愿意国王的A儿子作为他们的领袖,而某些城市更看好B,而为了交通的便捷,如果划分后的公路连接两个同一个国家的城市,那么更利于城市之间的交流。于是大臣们设计了一种对土地划分的评分机制,具体如下:
1. 对于城市i,如果它划分给A国,将得到VA[i]的得分;划分给B国,将得到VB[i]的得分。
2. 对于一条公路i,如果它连接两个A国的城市,将得到EA[i]的得分;连接两个B国的城市,将得到EB[i]的得分;否则,这条公路将失去意义,将扣除EC[i]的得分。
现请你找到最优的土地划分,使得这种它的评分最高。
Input
第一行包含两个整数N,M,含义如问题描述所示。
接下来一行N-2个非负整数,表示VA[2..N-1]。
接下来一行N-2个非负整数,表示VB[2..N-1]。
接下来M行,每行五个非负整数描述一条公路:X Y EA[i] EB[i] EC[i],含义如问题描述所示。
Output
输出有且仅有一个整数,表示最高评分。
Sample Input
3 3
8
9
1 2 2 6 2
2 3 8 5 7
1 3 9 4 1
Sample Output
11
【样例说明
A国仅有1号点,B国有2号和3号点。
评分=VB[2]+EB[2]-EC[1]-EC[3]=9+5-2-1=11。
HINT
【数据说明】
数据点 N M 备注
1-2 <=20 <=200 无
3-4 <=5000 <=10000 VA、VB、EA、EB均为0
5-6 <=5000 <=10000 EC均为0
7-10 <=10000 <=40000 无
保证运算过程中及最终结果不超过32位带符号整数类型的表示范围
有经验的很快就看出是最小割
建图
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<string>
#include<bitset>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
void print(int x)
{if(x<0)x=-x,putchar('-');if(x>=10)print(x/10);putchar(x%10+'0');}
const int N=100100,inf=0X3f3f3f3f;
int ecnt=1,last[N];
struct EDGE{int to,nt,val;}e[10001000];
inline void readd(int u,int v,int val)
{e[++ecnt]=(EDGE){v,last[u],val};last[u]=ecnt;}
inline void add(int u,int v,int val)
{readd(u,v,val);readd(v,u,0);}
int tot,n,m,S=0,T=N-1;
int q[N],d[N];
bool bfs()
{
memset(d,0,sizeof(d));
register int head=0,tail=1,u,i;
d[S]=1;q[head]=S;
while(head<tail)
{
u=q[head++];
for(i=last[u];i;i=e[i].nt)if(e[i].val&&!d[e[i].to])
{
d[e[i].to]=d[u]+1;
q[tail++]=e[i].to;
}
}
return d[T];
}
int dfs(int u,int lim)
{
if(!lim||T==u){return lim;}
int res=0,tmp;
for(int i=last[u];i;i=e[i].nt)
if(d[e[i].to]==d[u]+1&&e[i].val)
{
tmp=dfs(e[i].to,min(e[i].val,lim));
lim-=tmp;res+=tmp;e[i].val-=tmp;e[i^1].val+=tmp;
if(!tmp)d[e[i].to]=-1;if(!lim)break;
}
return res;
}
int mxflow;
void dinic()
{while(bfs())mxflow+=dfs(S,inf);}
int main()
{
n=read();m=read();
register int i,u,v,a,b,c,sum=0;
for(i=2;i<n;++i){a=read();add(S,i,a);sum+=a;}
for(i=2;i<n;++i){b=read();add(i,T,b);sum+=b;}
add(S,1,inf);add(n,T,inf);
tot=n;
while(m--)
{
u=read();v=read();a=read();b=read();c=read();
add(S,++tot,a);add(tot,u,inf);add(tot,v,inf);
add(++tot,T,b);add(u,tot,inf);add(v,tot,inf);
readd(u,v,c);readd(v,u,c);
sum+=a+b;
}
dinic();
print(sum-mxflow);puts("");
return 0;
}
/*
3 3
8
9
1 2 2 6 2
2 3 8 5 7
1 3 9 4 1
11
*/