hdu 4183(最大流)

原创 2016年05月30日 10:20:01

Pahom on Water

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)


Problem Description
Pahom on Water is an interactive computer game inspired by a short story of Leo Tolstoy about a poor man who, in his lust for land, forfeits everything. The game's starting screen displays a number of circular pads painted with colours from the visible light spectrum. More than one pad may be painted with the same colour (defined by a certain frequency) except for the two colours red and violet. The display contains only one red pad (the lowest frequency of 400 THz) and one violet pad (the highest frequency of 789 THz). A pad may intersect, or even contain another pad with a different colour but never merely touch its boundary. The display also shows a figure representing Pahom standing on the red pad.
The game's objective is to walk the figure of Pahom from the red pad to the violet pad and return back to the red pad. The walk must observe the following rules:
1.If pad α and pad β have a common intersection and the frequency of the colour of pad α is strictly smaller than the frequency of the colour of pad β, then Pahom figure can walk from α to β during the walk from the red pad to the violet pad
2. If pad α and pad β have a common intersection and the frequency of the colour of pad α is strictly greater than the frequency of the colour of pad β, then Pahom figure can walk from α to β during the walk from the violet pad to the red pad
3. A coloured pad, with the exception of the red pad, disappears from display when the Pahom figure walks away from it.
The developer of the game has programmed all the whizzbang features of the game. All that is left is to ensure that Pahom has a chance to succeed in each instance of the game (that is, there is at least one valid walk from the red pad to the violet pad and then back again to the red pad.) Your task is to write a program to check whether at least one valid path exists in each instance of the game.
 

Input
The input starts with an integer K (1 <= K <= 50) indicating the number of scenarios on a line by itself. The description for each scenario starts with an integer N (2 <= N <= 300) indicating the number of pads, on a line by itself, followed by N lines that describe the colors, locations and sizes of the N pads. Each line contains the frequency, followed by the x- and y-coordinates of the pad's center and then the radius. The frequency is given as a real value with no more than three decimal places. The coordinates and radius are given, in meters, as integers. All values are separated by a single space. All integer values are in the range of -10,000 to 10,000 inclusive. In each scenario, all frequencies are in the range of 400.0 to 789.0 inclusive. Exactly one pad will have a frequency of “400.0” and exactly one pad will have a frequency of “789.0”.
 

Output
The output for each scenario consists of a single line that contains: Game is VALID, or Game is NOT VALID
 

Sample Input
2 2 400.0 0 0 4 789.0 7 0 2 4 400.0 0 0 4 789.0 7 0 2 500.35 5 0 2 500.32 5 0 3
 

Sample Output
Game is NOT VALID Game is VALID
 
题意:有多个点,每个点给出坐标与半径,加入两个点相交,就可以从这两个点走。题目要求先从起点到终点,再从终点回到起点。从起点到终点的过程中,只能从频率小的走到频率大的点(前提是两点相交),从终点到起点的过程中,只能从频率大的走到频率小的。在走的过程中,除了起点与终点,别的只要走过就会消失,就是说只能走一次。问可不可以从起点到终点又回到起点。
解题思路:这个题我一开始的想法是拆点,但似乎并不能起到限制每个点只能走一次的作用,所以只好想别的办法了。之后我的想法就直接限制边,每条边的容量为1,这样跑最大流只要大于等于2,就一定是满足要求的。因为容量为1,代表着这一条边的两个顶点都只能经过一次,而最大流大于等于2是因为要从终点返回,那我们就可以认为从源点出发的几条流汇聚到汇点。此外,如果源点和汇点都能直接到达,就直接输出了。这道题只要想清了就很简单了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;

const int maxn = 305;
const int inf = 0x3f3f3f3f;
struct Node
{
	double f;
	int x,y,r;
}p[maxn];
struct Edge
{
	int v,flow,next;
}edge[maxn*maxn];
int n,cnt,Head[maxn],layer[maxn];

void addedge(int u,int v,int flow)
{
	edge[cnt].v = v;  
    edge[cnt].flow = flow;  
    edge[cnt].next = Head[u];  
    Head[u] = cnt++;  
  
    swap(u, v);  
  
    edge[cnt].v = v;  
    edge[cnt].flow = 0;  
    edge[cnt].next = Head[u];  
    Head[u] = cnt++;  
}

bool cmp(Node a,Node b)
{
	return a.f < b.f;
}

int dist(Node a,Node b)
{
	return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}

bool bfs(int start, int End)  
{  
    queue<int> Q;
	Q.push(start);  
    memset(layer, 0, sizeof(layer));  
    layer[start] = 1;  
    while(Q.size())  
    {  
        int u = Q.front();
		Q.pop();  
        if(u == End) return true;  
        for(int j = Head[u]; j != -1; j = edge[j].next)  
        {  
            int v = edge[j].v;  
            if(layer[v] == 0 && edge[j].flow)  
            {  
                layer[v] = layer[u] + 1;  
                Q.push(v);  
            }  
        }  
    }  
    return false;  
}  

int dfs(int u, int MaxFlow, int End)  
{  
    if(u == End) return MaxFlow;  
    int uflow = 0;  
    for(int j = Head[u]; j != -1; j = edge[j].next)  
    {  
        int v = edge[j].v;  
        if(layer[v] == layer[u] + 1 && edge[j].flow)  
        {  
            int flow = min(MaxFlow - uflow, edge[j].flow);  
            flow = dfs(v, flow, End);  
            edge[j].flow -= flow;  
            edge[j^1].flow += flow;  
            uflow += flow;  
            if(uflow == MaxFlow)break;  
        }  
    }  
    if(uflow == 0)  
        layer[u] = 0;  
    return uflow;  
}  

int dinic(int start, int End)  
{  
    int MaxFlow = 0;  
    while(bfs(start, End) == true)  
        MaxFlow += dfs(start,inf,End);  
    return MaxFlow;  
}  

int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		for(int i = 1; i <= n; i++)
			scanf("%lf%d%d%d",&p[i].f,&p[i].x,&p[i].y,&p[i].r);
		memset(Head,-1,sizeof(Head));
		cnt = 0;
		sort(p+1,p+1+n,cmp);
		for(int i = 1; i < n; i++)
			for(int j = i + 1; j <= n; j++)
			{
				if(dist(p[i],p[j]) < (p[i].r + p[j].r) * (p[i].r + p[j].r))
					addedge(i,j,1);
			}
		if(dist(p[1],p[n]) < (p[1].r + p[n].r) * (p[1].r + p[n].r))
			printf("Game is VALID\n");
		else{
			int ans = dinic(1,n);
			if(ans >= 2)
				printf("Game is VALID\n");
			else printf("Game is NOT VALID\n");
		}
	}
	return 0;
}


HDU 4183Pahom on Water(网络流之最大流)

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4183 这题题目意思很难看懂。。我看了好长时间也没看懂。。最终是从网上找的翻译。。我就在这翻译一下吧。...
  • u013013910
  • u013013910
  • 2014年06月17日 20:49
  • 1129

最大流 hdu 4183

/** hdu 4183 求两点之间来回不重复的两条路就是要求从起点到终点至少有两条不重复的路径,最大流大于等于2即可 **/ #include #include #include #incl...
  • mtxxxx
  • mtxxxx
  • 2017年02月28日 19:14
  • 110

hdu 最大流水题集锦。。。

源自--------------------------------Ice_Crazy(死之前应该会继续更新的。。。) 网络流水题:hdu1532、hdu3549、hdu2732(拆点、经典题...
  • Ice_Crazy
  • Ice_Crazy
  • 2013年08月05日 18:22
  • 3551

HDU 4183 最大流模板题

Pahom on WaterTime Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tot...
  • qq_31138083
  • qq_31138083
  • 2016年08月03日 09:32
  • 163

ACM hdu5352 最小费用最大流 模板 网络流

先建图,求字典序最小,转化成前面的费用较大,的费用流 for (int i=0; i 2015多校第5场-hdu5352 起初用ISAP最大流WA了,再后来用了费用流模板TLE,最后使用了大白书...
  • nickwong_
  • nickwong_
  • 2015年08月04日 20:44
  • 1612

hdu4888 最大流(构造矩阵)

题意:       让你构造一个矩阵,满足每一行的和,和每一列的和都等于他给的,还要判断答案是 否唯一,还有一点就是矩阵内所有的数字都是[0,k]范围的。 思路:       ...
  • u013761036
  • u013761036
  • 2014年07月30日 17:45
  • 369

HDU 3667Transportation(最小费用最大流)拆边,经典

Transportation Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
  • u010372095
  • u010372095
  • 2015年06月27日 21:47
  • 837

hdu 1083 Courses (简单二分匹配)

Courses Problem Description Consider a group of N students and P courses. Each student visits zero,...
  • u011721440
  • u011721440
  • 2014年03月11日 20:14
  • 624

HDU3081 3081 Marriage Match II(中等,好题)([二分最大流]+并查集)

题意:n个女孩,要和n个男孩配对,当每一个女孩都配对成功的时候,进入下一轮。每次都是女孩选择男孩,同时还告诉你哪些女孩和男孩之间没有吵过架,配对的原则是她们之间没有吵过架,同时女孩选择的男孩也不能和她...
  • u013167299
  • u013167299
  • 2015年09月24日 11:27
  • 196

HDU 4940 无源无汇上下界最大流

对于每条有向边lai's
  • ipqhjjybj
  • ipqhjjybj
  • 2014年08月13日 12:21
  • 1294
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:hdu 4183(最大流)
举报原因:
原因补充:

(最多只允许输入30个字)