2014 Nordic Collegiate Programming Contest A Amanda Lounges

题意:给n个点和m条信息,每条信息表示x和y中有z个休息室,问能不能有一种符合条件且休息室个数最少的方案。

读入数据时,先判断z,若z等于2,则给x,y都染上色1,若x,y中有颜色0 则不行,若z等于0,则给x,y都染上色0,若x,y中有颜色1 则不行。若z=1,就在x,y间建一条边。

先以已经有颜色的点为起始点去dfs染色,染色过程中出现矛盾就不行
再对其他没有颜色的点dfs染色,如果有矛盾就不行,否则答案加上两种颜色个数中较小的

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 2e5 + 10;
int n, m, col[N], h[N], cnt, vis[N], f, ans, sum, ct;
struct node {
    int v, net;
} no[N << 2];
void add(int u, int v) {
    no[cnt].v = v;
    no[cnt].net = h[u];
    h[u] = cnt++;
}
bool dfs1(int x, int co) {
    vis[x] = 1;
    col[x] = co;
    if(co == 1)
        ans++;
    for(int i = h[x]; ~i; i = no[i].net) {
        int v = no[i].v;
        if(col[v] == col[x])
            return false;
        if(!vis[v] && col[v] == -1) {
            if(!dfs1(v, co ^ 1))
                return false;
        }
    }
    return true;
}
bool dfs2(int x, int co) {
    vis[x] = 1;
    col[x] = co;
    if(co == 1)
        ct++;
    sum++;
    for(int i = h[x]; ~i; i = no[i].net) {
        int v = no[i].v;
        if(col[v] == col[x])
            return false;
        if(!vis[v] && col[v] == -1) {
            if(!dfs2(v, co ^ 1))
                return false;
        }
    }
    return true;
}
int main() {
    memset(col, -1, sizeof col);
    memset(h, -1, sizeof h);
    cin >> n >> m;
    for(int u, v, w, i = 1; i <= m; i++) {
        cin >> u >> v >> w;
        if(w == 0) {
            if(col[u] == 1 || col[v] == 1)
                f = 1;
            col[u] = col[v] = 0;
        }
        if(w == 2) {
            if(col[u] == 0 || col[v] == 0)
                f = 1;
            col[u] = col[v] = 1;
        }
        if(w == 1) {
            if((col[u] == 1 && col[v] == 1) || (col[u] == 0 && col[v] == 0))
                f = 1;
            add(u, v);
            add(v, u);
        }
    }
    for(int i = 1; i <= n; i++) {
        if(!vis[i] && col[i] != -1) {
            if(!dfs1(i, col[i]))
                f = 1;
        }
    }
    for(int i = 1; i <= n; i++) {
        if(col[i] == -1) {
            sum = 0, ct = 0;
            if(!dfs2(i, 1))
                f = 1;
            ans += min(ct, sum - ct);
        }
    }
    if(!f)
        cout << ans;
    else
        cout << "impossible";
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值