SPOJ IM_Intergalactic Map

判断能否从一个点同时找出两条不相交的路径到另外两个点。

保证路径不相交,那么需要拆点。然后?好像就没什么了,直接最大流即可。

不过,,,不需要求出所有的最大流,只要跑两次EK看看能否增广两次就行了。

召唤代码君:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#define maxn 2001000
#define maxm 5002000
using namespace std;

int L[maxn],R[maxn],Li[maxn],Ri[maxn];
int to[maxm],next[maxm],c[maxm],first[maxn],edge,node;
int from[maxn],tag[maxn],TAG=520;
int Q[maxm],bot,top;
int n,m,s,t,T;

int addnode()
{
    first[++node]=-1;
    return node;
}

void addedge(int U,int V)
{
    edge++;
    to[edge]=V,c[edge]=1,next[edge]=first[U],first[U]=edge;
    edge++;
    to[edge]=U,c[edge]=0,next[edge]=first[V],first[V]=edge;
}

void _input()
{
    int U,V;
    node=0,edge=-1;
    scanf("%d%d",&n,&m);
    while (m--)
    {
        scanf("%d%d",&U,&V);
        if (Li[U]!=TAG) Li[U]=TAG,L[U]=addnode(),R[U]=addnode(),addedge(L[U],R[U]);
        if (Li[V]!=TAG) Li[V]=TAG,L[V]=addnode(),R[V]=addnode(),addedge(L[V],R[V]);
        addedge(R[U],L[V]),addedge(R[V],L[U]);
    }
    t=addnode();
    if (Li[2]==TAG) s=R[2];
        else s=addnode();
    if (Li[1]==TAG) addedge(R[1],t);
    if (Li[3]==TAG) addedge(R[3],t);
}

bool EK()
{
    Q[bot=top=1]=s,tag[s]=++TAG,from[s]=-1;
    while (bot<=top)
    {
        int cur=Q[bot++];
        for (int i=first[cur]; i!=-1; i=next[i])
            if (c[i]>0 && tag[to[i]]!=TAG)
            {
                Q[++top]=to[i],from[to[i]]=i,tag[to[i]]=TAG;
                if (to[i]==t)
                {
                    for (int k=t; from[k]!=-1; k=to[from[k]^1])
                        c[from[k]]--,c[from[k]^1]++;
                    return true;
                }
            }
    }
    return false;
}

int main()
{
    scanf("%d",&T);
    while (T--)
    {
        _input();
        if (EK() && EK()) puts("YES");
            else puts("NO");
    }
    return 0;
}

SPOJ IM_Intergalactic Map

时间: 2024-11-13 08:21:28

SPOJ IM_Intergalactic Map的相关文章

SPOJ 962 Intergalactic Map

Intergalactic Map Time Limit: 6000ms Memory Limit: 262144KB This problem will be judged on SPOJ. Original ID: IM64-bit integer IO format: %lld      Java class name: Main Jedi knights, Qui-Gon Jinn and his young apprentice Obi-Wan Kenobi, are entruste

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

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

SPOJ 3273

传送门: 这是一道treap的模板题,不要问我为什么一直在写模板题 依旧只放代码 1 //SPOJ 3273 2 //by Cydiater 3 //2016.8.31 4 #include <iostream> 5 #include <cstring> 6 #include <ctime> 7 #include <cmath> 8 #include <cstdlib> 9 #include <string> 10 #include

SPOJ CRAN02 - Roommate Agreement

题目链接:http://www.spoj.com/problems/CRAN02/ 题目大意:N个数字组成的序列,和为0的连续子序列的个数.N<1e6 解题思路:计算前缀和,统计每个数字出现的次数,那么对于数字sum[i], 如果存在k个sum[i],则代表有C(k, 2)个序列和为0,而如果sum[i] = 0,则还要累加上对应的k值. 代码: 1 ll n; 2 int a[maxn]; 3 ll sum[maxn]; 4 map<int, int> mmp; 5 6 void so

SPOJ 1043 Can you answer these queries I 求任意区间最大连续子段和 线段树

题目链接:点击打开链接 维护区间左起连续的最大和,右起连续的和.. #include <cstdio> #include <iostream> #include <algorithm> #include <string.h> #include <math.h> #include <vector> #include <map> using namespace std; #define N 50050 #define Lson

bzoj 2588: Spoj 10628. Count on a tree LCA+主席树

2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个询问的u是明文. Input 第一行两个整数N,M. 第二行有N个整数,其中第i个整数