比赛 20160415 评测结果 AAAWWWWWWW
题目名称 能量网络 最终得分 30
用户昵称 dydxh 运行时间 0.395 s
代码语言 C++ 内存使用 4.87 MiB
提交时间 2016-04-15 11:47:54
显示代码纯文本
/*
Problem:Energynet;
Language:c++;
by dydxh;
Date:2016.04.15;
*/
#include<algorithm>
#include<iostream>
#include<cstring>
#include<utility>
#include<cstdlib>
#include<cstdio>
#include<string>
#include<vector>
#include<ctime>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define ll long long
#define ull unsigned long long
using namespace std;
const int oo=2000000000;
const int maxn=1005;
const int maxm=50005;
typedef pair<int,int> Pii;
int n,m,Len=1,Super_s,Super_e;
int A[maxn],B[maxn],L[maxn],R[maxn];
Pii E[maxm];
int Linkk[maxn<<1];
struct edge{
	int y,next,v;
}e[((maxn<<2)+(maxm<<2))<<1];
inline int read(){
	int x=0;bool flag=false;char ch=getchar();
	while(ch>'9' || ch<'0'){if(ch=='-') flag=true;ch=getchar();}
	while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return flag?-x:x;
}
void Insert(int a,int b,int c){
	e[++Len].next=Linkk[a],Linkk[a]=Len,e[Len].y=b,e[Len].v=c;
	if(c!=-1)
		e[++Len].next=Linkk[b],Linkk[b]=Len,e[Len].y=a,e[Len].v=0;
	//printf("%d->%d %d\n",a,b,c);
}
void Initialize(){
	Super_s=0,Super_e=n<<1|1;
	for(int i=1;i<=n;i++) A[i]=read();
	for(int i=1;i<=n;i++) B[i]=read();
	for(int i=1;i<=m;i++) E[i].first=read(),E[i].second=read();
	for(int i=1;i<=n;i++) L[i]=i,R[i]=n+i;
	sort(E+1,E+1+m);
	int Cnt=0;
	for(int i=1;i<=m;i++){
		if(E[i].first==E[i-1].first && E[i].second==E[i-1].second) continue;
		E[++Cnt]=E[i];
	}
	m=Cnt;
}
Pii Tor[maxn];
void Build_Graph(){
	for(int i=1;i<=n;i++) Insert(L[i],R[i],oo);
	for(int i=1;i<=n;i++) Insert(R[i],Super_e,B[i]);
	for(int i=1,j=1;i<=m;i=j+1){
		int Cnt=0;
		while(j<m && E[j+1].first==E[i].first) j++;
		for(int k=i;k<=j;k++) Tor[++Cnt]=make_pair(A[E[k].second],E[k].second);
		sort(Tor+1,Tor+1+Cnt);
		Insert(Super_s,R[Tor[Cnt].second],Tor[Cnt].first);
		for(int j=Cnt-1;j>=1;j--){
			//int v=min(Tor[j].first,max(Tor[j+1].first-B[Tor[j+1].second],0));
			Insert(R[Tor[j+1].second],L[Tor[j].second],oo);
			//Insert(R[Tor[j+1].second],L[Tor[j].second],Tor[j+1].first-B[Tor[j+1].second]);
			//Insert(R[Tor[j+1].second],L[Tor[j].second],Tor[j].first-Tor[j-1].first);
		}
	}
}
int Head,Tail;
int Q[maxn<<1],Level[maxn<<1];
bool Make_Level(){
	memset(Level,-1,sizeof(Level));
	Head=0,Tail=1,Q[1]=Super_s,Level[Super_s]=0;
	while(Head<Tail){
		int Tn=Q[++Head];
		for(int i=Linkk[Tn];i;i=e[i].next){
			int Tmp=e[i].y;
			if(Level[Tmp]!=-1 || e[i].v==0) continue;
			Level[Tmp]=Level[Tn]+1,Q[++Tail]=Tmp;
		}
	}
	return Level[Super_e]!=-1;
}
inline int min(const int &a,const int &b){return a<b?a:b;}
int Dfs(int x,int Flow){
	if(x==Super_e) return Flow;
	int D=0,Maxx=0;
	for(int i=Linkk[x];i && Maxx<Flow;i=e[i].next){
		int Tn=e[i].y;
		if(Level[Tn]!=Level[x]+1 || e[i].v==0) continue;
		D=Dfs(Tn,min(Flow-Maxx,e[i].v));
		if(D) Maxx+=D,e[i^1].v+=D,e[i].v-=D;
	}
	if(Maxx==0) Level[x]=-1;
	return Maxx;
}
int Ans;
int Exist[maxn];
void Calc(){
	int Total=0;
	for(int i=1;i<=n;i++){
		if(Exist[i]==false) Total+=B[i];
		int Maxx=0;
		for(int j=Linkk[i];j;j=e[j].next){
			int Tn=e[j].y;
			if(Exist[Tn]==false) continue;
			Maxx=max(Maxx,A[Tn]);
		}
		Total+=Maxx;
	}
	if(Ans>Total){
		Ans=Total;
		//for(int i=1;i<=n;i++) printf("%d ",Exist[i]);
		//printf("\n%d\n",Ans);
	}
}
void Dfss(int x){
	if(x==n+1){
		Calc();
		return ;
	}
	Exist[x]=true;
	Dfss(x+1);
	Exist[x]=false;
	Dfss(x+1);
}
void Brute(){
	Ans=oo;
	for(int i=1;i<=n;i++) A[i]=read();
	for(int i=1;i<=n;i++) B[i]=read();
	for(int i=1;i<=m;i++){
		int x=read(),y=read();
		Insert(x,y,-1);
	}
	Dfss(1);
	cout<<Ans<<endl;
}
int main(){
	freopen("energynet.in","r",stdin);
	freopen("energynet.out","w",stdout);
	n=read(),m=read();
	if(n<=20)
		Brute();
	else{
		Initialize();
		Build_Graph();
		while(Make_Level()) Ans+=Dfs(Super_s,oo);
		cout<<Ans<<endl;
	}
	//cout<<"Time has passed:"<<1.0*clock()/1000<<"s!"<<endl;
    return 0;
}