QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#421581#961. Smol Vertex Cover_yjhTL 0ms0kbC++145.0kb2024-05-25 21:49:422024-05-25 21:49:42

Judging History

你现在查看的是最新测评结果

  • [2024-05-25 21:49:42]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:0kb
  • [2024-05-25 21:49:42]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
typedef unsigned int uint;
inline ll read() {
	ll x=0,f=1;char ch=getchar();
	while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();}
	while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
const int N=505;
namespace Match { //贺的
    int tot,tag[N],vis[N],ma[N],pre[N],f[N],n,m,ans;
    vector<int> v[N];queue<int> q;
    void init(int N,int M) {
    	n=N,m=M;ans=0;
    	for(int i=1;i<=n;i++) tag[i]=vis[i]=ma[i]=pre[i]=f[i]=0,v[i].clear();
    	while(!q.empty()) q.pop();
	}
    void addedge(int x,int y) {
    	v[x].push_back(y);v[y].push_back(x);
	}
    int find(int x) {
	    while(x!=f[x]) x=f[x]=f[f[x]];
		return x;
	}
    int lca(int x,int y) {
	    ++tot;
	    while(true) {
	    	if(x) {
	    		x=find(x);
				if(tag[x]==tot) return x;
	    		tag[x]=tot;x=pre[ma[x]];
	    	}
	    	swap(x,y);
	    }
    }
    void flower(int x,int y,int p) {
	    while(find(x)!=p) {
	    	pre[x]=y;y=ma[x];vis[y]=1;q.push(y);
		    if(find(x)==x) f[x]=p;
	    	if(find(y)==y) f[y]=p;
	    	x=pre[y];
    	}
    }
    void bfs(int st) {
    	for(int i=1;i<=n;++i) pre[i]=vis[i]=0,f[i]=i;
    	while(!q.empty()) q.pop();
    	vis[st]=1;q.push(st);
	    while(!q.empty()) {
	    	int x=q.front();q.pop();
	    	for(int y:v[x])
			    if(find(y)!=find(x)&&vis[y]!=2) {
		         	if(vis[y]==1) {
		   	    	    int l=lca(x,y);
						flower(x,y,l);flower(y,x,l);continue;
		        	}
		        	vis[y]=2; pre[y]=x;
		        	if(!ma[y]) {
		        		int px=y;
		        		while(px) {
			        		int py=pre[px],pz=ma[py];
			        		ma[px]=py;ma[py]=px;px=pz;
			        	}
			        	++ans;return;
			        }
			        vis[ma[y]]=1;q.push(ma[y]);
		        }
	    }
    }
    vector <array<int,2>> solve() {
    	vector <array<int,2>> ret;
    	for(int i=1;i<=n;i++) if(!ma[i]) bfs(i);
    	for(int i=1;i<=n;i++) if(ma[i]>i) ret.push_back({i,ma[i]});
    	return ret;
	}
}
namespace SAT {
    int n,cnt,sit[N][2],dfn[N<<1],isk[N<<1],low[N<<1],dnf,fm[N<<1],id;
    vector <int> v[N];
    stack <int> s;
    void init(int N) {
        n=N;cnt=0;
        for(int i=1;i<=n;i++) sit[i][0]=++cnt,sit[i][1]=++cnt;
        for(int i=1;i<=cnt;i++) v[i].clear(),low[i]=isk[i]=dfn[i]=fm[i]=0;
        while(!s.empty()) s.pop();dnf=id=0;
    }
    void addedge(array <int,2> s,array <int,2> t) {
        auto [a,b]=s;auto [c,d]=t;
        v[sit[a][b]].push_back({sit[c][d]});
        v[sit[c][d^1]].push_back({sit[a][b^1]});
    }
    void tarjan(int x) {
        dfn[x]=low[x]=++dnf;
        s.push(x);isk[x]=true;
        for(int to:v[x]) {
            if(!dfn[to]) {
                tarjan(to);
                low[x]=min(low[x],low[to]);
            }
            else if(isk[to]) {
                low[x]=min(low[x],dfn[to]);
            }
        }
        if(dfn[x]==low[x]) {
            ++id;
            while(s.top()!=x) {
                fm[s.top()]=id,isk[s.top()]=false;
                s.pop();
            }
            fm[s.top()]=id,isk[s.top()]=false;
            s.pop();
        }
    }
    bool check() {
        for(int i=1;i<=cnt;i++) if(!dfn[i]) tarjan(i);
        for(int i=1;i<=n;i++) if(fm[sit[i][0]]==fm[sit[i][1]]) return false;
        return true;
    }
    void print() {
        for(int i=1;i<n;i++) if(dfn[sit[i][1]]<dfn[sit[i][0]]) cout<<i<<' ';
        cout<<'\n';
    }
}
int n,m;
bool vis[N];
struct edge {
    int x,y;
}e[N*N];
vector <int> v[N];
map <array<int,2>,bool> mp;
void clear() {
    mp.clear();
	for(int i=1;i<=n;i++) v[i].clear(),vis[i]=false;
}
bool check() {
    SAT::init(n+1);
    for(int i=1;i<=m;i++) {
        auto [x,y]=e[i];
        if(vis[x]&&vis[y]) {
            SAT::addedge({x,0},{y,1});
            SAT::addedge({y,0},{x,1});
            if(mp[{x,y}]) {
                SAT::addedge({x,1},{y,0});
                SAT::addedge({y,1},{x,0});
            }
        }
        else if(vis[x]) {
            SAT::addedge({x,0},{n+1,0});
            SAT::addedge({x,0},{n+1,1});
        }
        else if(vis[y]) {
            SAT::addedge({y,0},{n+1,0});
            SAT::addedge({y,0},{n+1,1});
        }
        else return false;
    }
    return SAT::check();
}
void mian() {
	n=read(),m=read();clear();
	Match::init(n,m);
	for(int i=1;i<=m;i++) {
		int x=read(),y=read();
		v[x].push_back(y),v[y].push_back(x);
		Match::addedge(x,y);
        e[i]={x,y};
	}
	auto mt=Match::solve();
	for(auto [u,v]:mt) {
        vis[u]=vis[v]=true;
        mp[{u,v}]=mp[{v,u}]=true;
	}
	if(check()) {
        cout<<mt.size()<<'\n';
        SAT::print();
        return ;
	}
	for(int i=1;i<=n;i++) {
	    if(vis[i]) continue;
        vis[i]=true;
        if(check()) {
            cout<<mt.size()+1<<'\n';
            SAT::print();
            return ;
        }
        vis[i]=false;
	}
	cout<<"not smol\n";
}
int main() {
	int T=read();while(T--) mian();
	return 0;
}

詳細信息

Test #1:

score: 0
Time Limit Exceeded

input:

5 5
1 2
2 3
3 4
4 5
1 5

output:


result: