SPOJ 962 Intergalactic Map

Intergalactic Map

Time Limit: 6000ms

Memory Limit: 262144KB

This problem will be judged on SPOJ. Original ID: IM
64-bit integer IO format: %lld      Java class name: Main

Jedi knights, Qui-Gon Jinn and his young apprentice Obi-Wan Kenobi, are entrusted by Queen Padmé Amidala to save Naboofrom an invasion by the Trade Federation. They must leave Naboo immediately and go to Tatooine to pick up the proof of the Federation’s evil design. They then must proceed on to the Republic’s capital planet Coruscant to produce it in front of the Republic’s Senate. To help them in this endeavor, the queen’s captain provides them with an intergalactic map. This map shows connections between planets not yet blockaded by the Trade Federation. Any pair of planets has at most one connection between them, and all the connections are two-way. To avoid detection by enemy spies, the knights must embark on this adventure without visiting any planet more than once. Can you help them by determining if such a path exists?

Note - In the attached map, the desired path is shown in bold.

Input Description

The first line of the input is a positive integer t ≤ 20, which is the number of test cases. The descriptions of the test cases follow one after the other. The first line of each test case is a pair of positive integers n, m (separated by a single space). 2 ≤ n ≤ 30011 is the number of planets and m ≤ 50011 is the number of connections between planets. The planets are indexed with integers from 1 to n. The indices of Naboo, Tatooine and Coruscant are 1, 2, 3 respectively. The next m lines contain two integers each, giving pairs of planets that have a connection between them.

Output Description

The output should contain t lines. The ith line corresponds to the ith test case. The output for each test case should be YES if the required path exists and NO otherwise.

Example

Input
2
3 3
1 2
2 3
1 3
3 1
1 3

Output
YES
NO

Source

Fair Isaac Programming Challenge - prelims 2006

解题:不错的无向图拆点最大流。

由于要求每个点只通过一次,可以把点约束转化为边约束。边流量为1就是了。

很有意思的地方啊,S是与2‘相连,而不是2相连。原因嘛!在这道题目,我们需要从1到2再到3,不重复经过点。现在化成边了,也就是不重复经过边。很明显,从2进行两次增广,第一次到1,第二次到3.两次增广都造访了2号顶点,也就是如果S直接与2相连,由于2号点的约束,导致2号点只能造访一次,也就是2-2’这条边,所有只能增广一次。将S与2‘相连,就能进行多次增广了。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <climits>
 7 #include <vector>
 8 #include <queue>
 9 #include <cstdlib>
10 #include <string>
11 #include <set>
12 #include <stack>
13 #define LL long long
14 #define pii pair<int,int>
15 #define INF 0x3f3f3f3f
16 using namespace std;
17 const int maxn = 200000;
18 struct arc{
19     int to,flow,next;
20     arc(int x = 0,int y = 0,int z = -1){
21         to = x;
22         flow = y;
23         next = z;
24     }
25 };
26 arc e[maxn*10];
27 int head[maxn],d[maxn],cur[maxn];
28 int tot,S,T,n,m;
29 void add(int u,int v,int flow){
30     e[tot] = arc(v,flow,head[u]);
31     head[u] = tot++;
32     e[tot] = arc(u,0,head[v]);
33     head[v] = tot++;
34 }
35 int q[maxn],hd,tl;
36 bool bfs(){
37     hd = tl = 0;
38     memset(d,-1,sizeof(d));
39     q[tl++] = S;
40     d[S] = 1;
41     while(hd < tl){
42         int u = q[hd++];
43         for(int i = head[u]; ~i; i = e[i].next){
44             if(e[i].flow && d[e[i].to] == -1){
45                 d[e[i].to] = d[u] + 1;
46                 q[tl++] = e[i].to;
47             }
48         }
49     }
50     return d[T] > -1;
51 }
52 int dfs(int u,int low){
53     if(u == T) return low;
54     int tmp = 0,a;
55     for(int &i = cur[u]; ~i; i = e[i].next){
56         if(e[i].flow && d[e[i].to] == d[u]+1&&(a=dfs(e[i].to,min(e[i].flow,low)))){
57             e[i].flow -= a;
58             e[i^1].flow += a;
59             tmp += a;
60             low -= a;
61             if(!low) break;
62         }
63     }
64     if(!tmp) d[u] = -1;
65     return tmp;
66 }
67 int dinic(){
68     int ans = 0;
69     while(bfs()){
70         memcpy(cur,head,sizeof(head));
71         ans += dfs(S,INF);
72     }
73     return ans;
74 }
75 int main() {
76     int cs,u,v;
77     scanf("%d",&cs);
78     while(cs--){
79         scanf("%d %d",&n,&m);
80         memset(head,-1,sizeof(head));
81         S = tot = 0;
82         T = n<<1|1;
83         for(int i = 0; i < m; ++i){
84             scanf("%d %d",&u,&v);
85             if(u > n || v > n) continue;
86             add(u+n,v,1);
87             add(v+n,u,1);
88         }
89         for(int i = 1; i <= n; ++i) add(i,i+n,1);
90         add(1+n,T,1);
91         add(3+n,T,1);
92         add(S,2+n,2);//注意细节啊
93         printf("%s\n",dinic() == 2?"YES":"NO");
94     }
95     return 0;
96 }

时间: 2024-12-28 08:30:14

SPOJ 962 Intergalactic Map的相关文章

SPOJ 962 Intergalactic Map (网络最大流)

http://www.spoj.com/problems/IM/ 962. Intergalactic Map Problem code: IM Jedi knights, Qui-Gon Jinn and his young apprentice Obi-Wan Kenobi, are entrusted by Queen Padmé Amidala to save Naboofrom an invasion by the Trade Federation. They must leave N

SPOJ IM - Intergalactic Map - [拆点最大流]

题目链接:http://www.spoj.com/problems/IM/en/ Time limit:491 ms Memory limit:1572864 kB Code length Limit:50000 B Jedi knights, Qui-Gon Jinn and his young apprentice Obi-Wan Kenobi, are entrusted by Queen Padmé Amidala to save Naboo from an invasion by th

Intergalactic Map SPOJ - IM

传送门 我觉得我写得已经和题解一模一样了,不知道为什么就是过不了..懒得拍了,反正不是很难,不太想浪费时间. 1~2~3的一条路径相当于从2~1的一条路径+2~3的一条路径,点不能重复经过,于是拆点. 1 //Achen 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdlib> 6 #include<vector> 7 #include&l

SPOJ962 Intergalactic Map(最大流)

题目问一张无向图能否从1点走到2点再走到3点,且一个点只走一次. 思维定势思维定势..建图关键在于,源点向2点连边,1点和3点向汇点连边! 另外,题目数据听说有点问题,出现点大于n的数据.. 1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #include<algorithm> 5 using namespace std; 6 #define INF (1<<30) 7 #de

Extension of write anywhere file system layout

A file system layout apportions an underlying physical volume into one or more virtual volumes (vvols) of a storage system. The underlying physical volume is an aggregate comprising one or more groups of disks, such as RAID groups, of the storage sys

Hive-1.2.1_03_DDL操作

Hive官方文档:Home-UserDocumentation Hive DDL官方文档:LanguageManual DDL 参考文章:Hive 用户指南 注意:各个语句的版本时间,有的是在 hive-1.2.1 之后才有的,这些语句我们在hive-1.2.1中是不能使用的. 注意:本文写的都是常用的知识点,更多细节请参考官网. 常用命令 1 select current_database(); # 当前使用哪个库 2 show databases; # 显示所有库名 3 show table

大数据--hive查询

一.全表查询和特定列查询 1.全表查询: ------------------------------------------------------------------- hive (db_test)> select * from dept;OKdept.deptno dept.dname dept.loc10 ACCOUNTING 170020 RESEARCH 180030 SALES 190040 OPERATIONS 1700Time taken: 0.306 seconds, F

SPOJ IM_Intergalactic Map

判断能否从一个点同时找出两条不相交的路径到另外两个点. 保证路径不相交,那么需要拆点.然后?好像就没什么了,直接最大流即可. 不过,,,不需要求出所有的最大流,只要跑两次EK看看能否增广两次就行了. 召唤代码君: #include <iostream> #include <cstdio> #include <cstring> #include <map> #define maxn 2001000 #define maxm 5002000 using name

SPOJ ADAFIELD Ada and Field(STL的使用:set,multiset,map的迭代器)题解

题意:n*m的方格,"0 x"表示x轴在x位置切一刀,"0 y"表示y轴在y位置切一刀,每次操作后输出当前面积最大矩形. 思路:用set分别储存x轴y轴分割的点,用multiset(可重复)储存x轴y轴边,每次输出最大的长和最大的宽的积.题目可能重复切.multiset如果直接erase(13)会把所有的13都删掉,如果只想删一个则erase(multiset.find(13)).第一次知道set自带二分... 这里multiset也可以用map<int, i