比赛 |
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;
}