题源
题意:
n
n
个点条边的无向图,判断其是否是弦图。
思路:
这个是判断弦图的裸题, 可以看陈丹琦的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;
}