比赛 |
20120420 |
评测结果 |
AAAWWWWWWW |
题目名称 |
狙击兵 |
最终得分 |
30 |
用户昵称 |
kaaala |
运行时间 |
0.000 s |
代码语言 |
C++ |
内存使用 |
0.00 MiB |
提交时间 |
2012-04-20 09:43:28 |
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<deque>
using namespace std;
const int oo=~0u>>2;
struct edge
{
int t,w;
edge *next,*back;
edge(int _t,int _w,edge *_next):t(_t),w(_w),next(_next){}
}*Map[410],*Lmap[410];
struct Node
{
int x,y;
}A[410];
int Q,N,M,maxflow,dist[410],S,T,val[410];
bool operator <(Node a,Node b)
{
return a.y<b.y||(a.y==b.y&&a.x<b.x);
}
void addedge(int s,int t,int w)
{
Map[s]=new edge(t,w,Map[s]);
Map[t]=new edge(s,0,Map[t]);
Map[s]->back=Map[t];
Map[t]->back=Map[s];
}
bool dinic_f()
{
deque<int>deq;
memset(dist,-1,sizeof(dist));
deq.push_back(S);
dist[S]=0;
while(!deq.empty())
{
int u=deq.front();
deq.pop_front();
for(edge *p=Map[u];p;p=p->next)
{
int t=p->t,w=p->w;
if(dist[t]==-1&&w)
{
dist[t]=dist[u]+1;
deq.push_back(t);
if(t==T)
return true;
}
}
}
return false;
}
void dinic_lable()
{
int now=1,v[410];
edge *pre[410];
for(int i=S;i<=T;i++)
Lmap[i]=Map[i];
v[now]=S;
while(now)
{
int u=v[now];
if(u==T)
{
int del=oo;
for(int i=now;i>1;i--)
del=min(del,pre[i]->w);
for(int i=now;i>1;i--)
{
pre[i]->w-=del;
pre[i]->back->w+=del;
if(!pre[i]->w)
now=i-1;
}
if(del!=oo)
maxflow+=del;
}
else
{
edge *&p=Lmap[u];
for(;p;p=p->next)
{
int t=p->t,w=p->w;
if(w&&dist[t]==dist[u]+1)
break;
}
if(p)
{
now++;
pre[now]=p;
v[now]=p->t;
}
else
{
now--;
dist[u]=-1;
}
}
}
}
void dinic()
{
while(dinic_f())
dinic_lable();
}
int main()
{
freopen("snipers.in","r",stdin);
freopen("snipers.out","w",stdout);
scanf("%d",&Q);
while(Q--)
{
scanf("%d%d",&N,&M);
S=0;
T=N;
N--;
for(int i=1;i<=N;i++)
scanf("%d",&val[i]);
for(int i=1;i<=M;i++)
scanf("%d%d",&A[i].x,&A[i].y);
sort(A+1,A+1+M);
for(int i=1;i<=M;i++)
{
if(A[i].y!=T)
addedge(A[i].x,A[i].y,val[A[i].y]);
else
addedge(A[i].x,A[i].y,oo);
}
dinic();
printf("%d\n",maxflow);
}
return 0;
}