ZOJ1015 Fishing Net(弦图判定)

题源

题意:
             n n 个点m条边的无向图,判断其是否是弦图。

思路:
             这个是判断弦图的裸题, 可以看陈丹琦的ppt

#include<bits/stdc++.h>
typedef long long ll;
const int maxn = 1e3 + 10;
using namespace std;

struct edge { int to, nxt; } G[maxn * maxn];
int n, m, T, kase = 1;
int vis[maxn], h[maxn], cnt;
int pos[maxn], check[maxn];

void add(int x, int y) { ++cnt; G[cnt].to = y; G[cnt].nxt = h[x]; h[x] = cnt; }

void scan_d(int &num) {
    num = 0; char ch = getchar();
    while(ch < '!') ch = getchar();
    while(ch >= '0' && ch <= '9') num = num * 10 + ch - '0', ch = getchar();
}

bool mcs() {
    for(int now = n; now >= 1; now--) {
        int mx = -1, mn = maxn * maxn, A = 0, B = 0;
        for(int i = 1; i <= n; i++) if(!pos[i] && check[i] > mx) { mx = check[i]; A = i; }
        pos[A] = now;
        for(int i = h[A]; i; i = G[i].nxt) {
            int v = G[i].to;
            if(!pos[v]) check[v]++;
            if(pos[v] > pos[A] && pos[v] < mn) { mn = pos[v]; B = v; }
        }
        for(int i = h[B]; i; i = G[i].nxt) {
            int v = G[i].to;
            vis[v] = true;
        }
        vis[B] = true;
        for(int i = h[A]; i; i = G[i].nxt) {
            int v = G[i].to;
            if(pos[v] > pos[A] && !vis[v]) return false;
        }
        for(int i = h[B]; i; i = G[i].nxt) {
            int v = G[i].to;
            vis[v] = false;
        }
        vis[B] = false;
    }
    return true;
}

int main() {
    while(1) {
        scan_d(n); scan_d(m);
        if(!(n + m)) break; cnt = 0;
        for(int i = 1; i <= n; i++) vis[i] = check[i] = pos[i] = pos[i] = h[i] = 0;
        for(int i = 1; i <= m; i++) {
            int u, v;
            //scanf("%d %d", &u, &v);
            scan_d(u); scan_d(v);
            add(u, v); add(v, u);
        }
        int ans = mcs();
        if(ans) printf("Perfect\n\n");
        else printf("Imperfect\n\n");

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值