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