1. 程式人生 > >[bzoj1116][POI2008][CLO]

[bzoj1116][POI2008][CLO]

har tar getch fin last .com spa name wap

題目鏈接

思路

可以先考慮一棵樹

技術分享圖片

如圖,如果是一棵樹我們肯定會想這樣子做,但是現在根沒有入度。所以現在需要再加入一條邊使他變成基環樹。

假如現在加入一條邊\(3-2\),那就會出現一個3-1-2-3的環。然後以這個環上的點為根,就可以找到很多棵滿足條件的樹

技術分享圖片

可以發現,這樣就解決了根沒有入度的問題。

結論

每一個與環相連通的點都是合法的,只要判斷是否存在不合法的點即可。

代碼

/*
* @Author: wxyww
* @Date:   2018-12-02 20:15:02
* @Last Modified time: 2018-12-02 20:21:40
*/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<bitset>
using namespace std;
typedef long long ll;
const int N = 100000 + 100,M = 200000 + 100;
ll read() {
    ll x=0,f=1;char c=getchar();
    while(c<'0'||c>'9') {
        if(c=='-') f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9') {
        x=x*10+c-'0';
        c=getchar();
    }
    return x*f;
}
int col[N],fa[N];
int find(int x) {
    return x == fa[x] ? x : fa[x] = find(fa[x]);
}
int main() {
    int n = read(),m = read();
    for(int i = 1;i <= n;++i) fa[i] = i;
    for(int i = 1;i <= m;++i) {
        int u = find(read()),v = find(read());
        if(u == v) {
            col[u] = 1;
            continue;
        }
        if(rand() & 1) swap(u,v);
        fa[u] = v;
        col[v] |= col[u];
    }
    for(int i = 1;i <= n;++i) {
        if(!col[find(i)]) {
            puts("NIE");
            return 0;
        }
    }
    puts("TAK");
    return 0;
}

一言

萬丈紅塵三杯酒,千秋大業一壺茶。 ——大智慧

[bzoj1116][POI2008][CLO]