P5361 题解
Solution
首先分析一下这个诡异的限制:
首先,如果
然后你发现,你让
首先考虑怎么求
第二问是一般图的最大独立集问题。据说它是 NPC 问题。
但是考虑到你并不一定要把最大独立集求出来。下面再给出一个算法:每次把度数最小的节点和它所有相邻节点取出来,并且把这个度数最小的节点放进独立集里面去。由于每个时刻度数最小点的度数必然小于等于
这个过程有点像 Dijkstra。于是你可以借鉴一下。
#include<bits/stdc++.h>
#define ffor(i,a,b) for(int i=(a);i<=(b);i++)
#define roff(i,a,b) for(int i=(a);i>=(b);i--)
using namespace std;
const int MAXN=1e4+10,MAXM=1e5+10;
int T,n,m,Deg[MAXN],deg[MAXN],in[MAXN];
pair<int,int> E[MAXM];
vector<int> G[MAXN];
int read(void) {
int s=0;
char ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9') s=(s<<1)+(s<<3)+(ch^48),ch=getchar();
return s;
}
struct Node {int u,dis;};
bool operator <(Node A,Node B) {return A.dis>B.dis;}
int vis[MAXN],res;
vector<int> ot,ans;
void solve(int mn=-1) {
priority_queue<Node> q;
ffor(i,1,n) vis[i]=0,deg[i]=Deg[i];
ffor(i,1,n) q.push({i,deg[i]});
int flg=0;
while(!q.empty()) {
int u=q.top().u;
q.pop();
if(vis[u]) continue;
vis[u]=1;
if(mn==-1) res=max(res,deg[u]);
else {
if(deg[u]>=mn) flg=1;
if(flg) ot.push_back(u);
}
for(auto v:G[u]) if(vis[v]==0) deg[v]--,q.push({v,deg[v]});
}
return ;
}
void Solve(void) {
ffor(i,1,n) vis[i]=0,deg[i]=Deg[i];
priority_queue<Node> q;
ffor(i,1,n) q.push({i,deg[i]});
while(!q.empty()) {
int u=q.top().u; q.pop();
if(vis[u]) continue;
vis[u]=1;
ans.push_back(u);
for(auto v:G[u]) {
if(vis[v]==0) {
vis[v]=1;
for(auto t:G[v]) if(vis[t]==0) deg[t]--,q.push({t,deg[t]});
}
}
}
}
int main() {
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
T=read();
while(T--) {
n=read(),m=read(),ot.clear();
ffor(i,1,n) deg[i]=0,G[i].clear();
ffor(i,1,m) {int u=read(),v=read();E[i]={min(u,v),max(u,v)};}
sort(E+1,E+m+1),m=unique(E+1,E+m+1)-E-1;
ffor(i,1,m) {
deg[E[i].first]++,deg[E[i].second]++;
G[E[i].first].push_back(E[i].second),G[E[i].second].push_back(E[i].first);
}
ffor(i,1,n) Deg[i]=deg[i];
res=*min_element(deg+1,deg+n+1),solve(),solve(res);
printf("%d ",(int)ot.size());for(auto id:ot) printf("%d ",id); puts("");
ans.clear(); Solve();
printf("%d ",(int)ans.size());for(auto pr:ans) printf("%d ",pr); puts("");
}
return 0;
}