2012天津賽區網絡賽第三題--Island Transport(hdu4280)

     題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=4280

     題意:有N個島嶼之間有M雙向條路,每條路每個小時最多能通過C個人,現在問一個小時內,最多能把多少個顧客從最西邊的島嶼送至最東邊的島嶼上。

     思路:網絡流,求最大流。建圖:每條路連接的兩個島嶼之間建立一條容量爲C的雙向邊,取超級源點與匯點,源點與最西邊的島嶼,匯點與最東邊的島嶼建立一條流量爲無窮大的邊。

      考點:網絡流,Dinic非遞歸版,如果使用遞歸版的Dinic,將RE!

Code:

#include <stdio.h>
#include <string.h>
#define MAXN 100010
#define INF 0x3f3f3f
struct Edge{
	int u;
	int v;
	int cap;
	int next;
}edge[MAXN*2];
int head[MAXN];
int level[MAXN];
int que[MAXN];
int stack[MAXN];
int cur[MAXN];
int tot;
void addedge(int u,int v,int cap)
{
	edge[tot].u = u;
	edge[tot].v = v;
	edge[tot].cap = cap;
	edge[tot].next = head[u];
	head[u] = tot;
	tot++;

	edge[tot].u = v;
	edge[tot].v = u;
	edge[tot].cap = cap;
	edge[tot].next = head[v];
	head[v] = tot;
	tot++;
}
int BFS(int src,int des)
{
	int i;
	int front=0,real=0;
	memset(level,-1,sizeof(level));
	que[real++] = src;
	level[src] = 0;
	while(front != real)
	{
		int u = que[front++];
		front = front%MAXN;
		for(i = head[u];i != -1;i = edge[i].next)
		{
			int v = edge[i].v;
			if(edge[i].cap > 0 && level[v] == -1)
			{
				level[v] = level[u] +1;
                que[real++] = v;
				real = real%MAXN;
				if(v == des)
					return 1;
			}
		}
	}
	return 0;
}
int dinic(int src,int des)
{
	int i;
	int res = 0;
	while(BFS(src,des))
	{
		memcpy(cur,head,sizeof(head));
		int u = src;
		int top = 0;
		while(1)
		{
			if(u == des)
			{
				int min = INF,id;
				for(i=0;i<top;i++)
				{
					if(edge[stack[i]].cap < min)
					{
						min = edge[stack[i]].cap;
						id = i;
					}
				}
				for(i=0;i<top;i++)
				{
					edge[stack[i]].cap -= min;
					edge[stack[i]^1].cap += min;
				}
				res += min;
				top = id;
				u = edge[stack[top]].u;
			}
			
			for(i=cur[u];i!=-1;i = cur[u] = edge[i].next)
				if(edge[i].cap !=0 && level[u] == level[edge[i].v] -1)
					break;
            
			if(cur[u] != -1)
			{
				stack[top++] = cur[u];
				u = edge[cur[u]].v;
			}
		
			else
			{
				if(top == 0)
					break;
				level[u] = -1;
				u = edge[stack[--top]].u;
			}
		}
	}
    return res;
}
int main()
{
	int i;
	int ncase;
	scanf("%d",&ncase);
	while(ncase--)
	{
		int n,m;
		int x,y,w;
		int max = -INF,min = INF;
		int idw,ide;
		scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++)
		{
			scanf("%d%d",&x,&y);
			if(x>max)
			{
				max = x;
				ide = i;
			}
			if(x<min)
			{
				min = x;
				idw = i;
			}
		}
		 tot = 0;
		 memset(head,-1,sizeof(head));
         addedge(0,idw,INF);
		 addedge(ide,n+1,INF);
         for(i=1;i<=m;i++)
		 {
			 scanf("%d%d%d",&x,&y,&w);
			 addedge(x,y,w);
		 }
        int ans = dinic(0,n+1);
		printf("%d\n",ans);
	}
	return 0;
}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章