SPOJ 962 IM - Intergalactic Map

一眼题,但是有个很坑的地方,我看了题目没注意。
就是输入数据会有无效输入……结果贡献了3发wa,还不断尝试开大数组……

传送门

题意:
给你一张无向图,让你从1点出发,经过2点,最后到3点,能否实现。每个点只能去一次。

思路:
肯定是拆点啦,容量设置成1即可。再从2开始跑,看流量能否为2。

AC Code

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>

using namespace std;
const int maxn = 66500;
const int inf = 0x3f3f3f3f;

int n, m, st, en, idx;
int level[maxn], cur[maxn];
int head[maxn];

struct node {
    int to;
    int nxt;
    int flow;
} edges[551000];

queue<int> que;

inline void addEdge(int u, int v, int flow)
{
    edges[idx].to = v;
    edges[idx].flow = flow;
    edges[idx].nxt = head[u];
    head[u] = idx++;
}

bool bfs()
{
    while (!que.empty())
        que.pop();
    memset(level, -1, sizeof level);
    que.push(st);
    level[st] = 0;
    int u;
    while (!que.empty()) {
        u = que.front();
        que.pop();
        for (int id = head[u]; ~id; id = edges[id].nxt) {
            int v = edges[id].to;
            if (edges[id].flow && level[v] == -1) {
                level[v] = level[u] + 1;
                que.push(v);
            }
        }
    }
    return level[en] != -1;
}

int dfs(int u, int low)
{
    int cflow;
    if (u == en)
        return low;
    for (int& id = cur[u]; ~id; id = edges[id].nxt) {
        int v = edges[id].to;
        if (edges[id].flow && level[v] == level[u] + 1
            && (cflow = dfs(v, min(low, edges[id].flow)))) {
            edges[id].flow -= cflow;
            edges[id ^ 1].flow += cflow;
            return cflow;
        }
    }
    return 0;
}

int dinic()
{
    int ans = 0, cflow;
    while (bfs()) {
        for (int i = 0; i <= 2 * n; i++)
            cur[i] = head[i];
        while ((cflow = dfs(st, inf)))
            ans += cflow;
    }
    return ans;
}

int main()
{
    int T, u, v;
    scanf("%d", &T);
    while (T--) {
        scanf("%d %d", &n, &m);
        memset(head, -1, sizeof head);
        idx = 0;
        for (int i = 1; i <= n; i++) {
            addEdge(i, i + n, 1);
            addEdge(i + n, i, 0);
        }
        while (m--) {
            scanf("%d %d", &u, &v);
            if (u < 1 || v < 1 || u > n || v > n)
                continue;
            addEdge(u + n, v, 1);
            addEdge(v + n, u, 1);
        }
        st = 2 + n, en = 2 * n + 1;
        addEdge(1 + n, en, 1);
        addEdge(en, 1 + n, 0);
        addEdge(3 + n, en, 1);
        addEdge(en, 3 + n, 0);
        if (dinic() == 2)
            puts("YES");
        else
            puts("NO");
    }
    return 0;
}