QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#425349#961. Smol Vertex CoveroceeffTL 0ms0kbC++143.4kb2024-05-30 09:10:432024-05-30 09:10:43

Judging History

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

  • [2024-05-30 09:10:43]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:0kb
  • [2024-05-30 09:10:43]
  • 提交

answer

/*
为什么我们可以直接跑sat?因为我们求出的是最大匹配,所以任意匹配的两端不可能都有相邻的未选点,否则容易增大匹配个数
因此对于每组匹配,我们将有相邻的未选点的那一个点(如果没有就随便)
于是可以调整方案使得没有相邻的点都取真!

3
5 5
1 2
2 3
3 4
4 5
1 5
3 0
5 10
1 2
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5

3
2 3 5
0

not smol
*/
#include<bits/stdc++.h>
#ifdef ONLINE_JUDGE
	#define getchar()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
	char buf[1<<21],*p1=buf,*p2=buf;
#endif
using namespace std;int read(){int num=0,f=1;char c;while(!isdigit(c=getchar()))if(c=='-')f=-1;while(isdigit(c))num=num*10+(c&15),c=getchar();return num*f;}void write(int x,char ch=' '){int F[20],cnt=0;if(!x)putchar('0');if(x<0)putchar('-'),x=-x;while(x)F[cnt++]=x%10+'0',x/=10;while(cnt)putchar(F[--cnt]);putchar(ch);}
namespace Main
{
    const int N=510,M=N*N;
    struct SAT{int n,k,q,ti,dfn[N<<1],low[N<<1],st[N<<1],scc[N<<1],top,head[N<<1],to[M<<2],nxt[M<<2],tot;void clear(int nn){n=nn,k=n>>1,memset(head,0,(n+1)<<2),memset(dfn,0,(n+1)<<2),memset(scc,0,(n+1)<<2),q=ti=tot=top=0;}void link(int x,int y){to[++tot]=y,nxt[tot]=head[x],head[x]=tot;}
    void tarjan(int x){dfn[x]=low[x]=++ti,st[++top]=x;for(int i=head[x];i;i=nxt[i])if(!dfn[to[i]])tarjan(to[i]),low[x]=min(low[x],low[to[i]]);else if(!scc[to[i]])low[x]=min(low[x],dfn[to[i]]);if(dfn[x]==low[x])for(++q,st[top+1]=0;st[top+1]!=x;--top)scc[st[top]]=q;}bool cal(){for(int i=1;i<=n;++i)if(!dfn[i])tarjan(i);for(int i=1;i<=k;++i)if(scc[i]==scc[i+k])return 0;return 1;}bool C(int x){return scc[x]<scc[x+k];}}A;
    int n,m,q,x,y,z,head[N],to[M],nxt[M],tot,ti,id[N],fa[N],mp[N],pre[N],vis[N];vector<int>ans;queue<int>que;int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}void link(int x,int y){to[++tot]=y,nxt[tot]=head[x],head[x]=tot;}
    int lca(int x,int y){for(++ti,x=find(x),y=find(y);id[x]!=ti;){id[x]=ti,x=find(pre[mp[x]]);if(y)swap(x,y);}return x;}void blo(int x,int y,int z){for(;find(x)!=z;){pre[x]=y,y=mp[x];if(vis[y]==2)vis[y]=1,que.push(y);if(find(x)==x)fa[x]=z;if(find(y)==y)fa[y]=z;x=pre[y];}}
    bool aug(int s){for(int i=1;i<=n;++i)fa[i]=i;for(memset(vis,0,(n+1)<<2),memset(pre,0,(n+1)<<2);que.size();que.pop());for(vis[s]=1,que.push(s);que.size();){x=que.front(),que.pop();for(int i=head[x];i;i=nxt[i])if(find(x)!=find(y=to[i])&&vis[y]!=2){if(!vis[y]){vis[y]=2,pre[y]=x;if(!mp[y]){for(int j=y;j;j=x)x=mp[pre[j]],mp[mp[j]=pre[j]]=j;return 1;}vis[mp[y]]=1,que.push(mp[y]);}else z=lca(x,y),blo(x,y,z),blo(y,x,z);}}return 0;}
    void clr(){memset(head,0,(n+1)<<2),memset(mp,0,(n+1)<<2),q=tot=0;}bool calc(int x){A.clear(n<<1);for(int i=1;i<=n;++i)for(int j=head[i];j;j=nxt[j])A.link(i+n,to[j]);for(int i=1;i<=n;++i)if(!mp[i])(i!=x?A.link(i,i+n):A.link(i+n,i));else if(i!=x&&mp[i]!=x)A.link(i,mp[i]+n);return A.cal();}
    void main(){for(n=read(),m=read(),clr();m--;)x=read(),y=read(),link(x,y),link(y,x);for(int i=1;i<=n;++i)if(!mp[i])aug(i);for(int i=0;i<=n;++i)if(calc(i)){ans.clear();for(int j=1;j<=n;++j)if(A.C(j))ans.push_back(j);write((int)ans.size(),'\n');for(auto j:ans)write(j);putchar('\n');return;}printf("not smol\n");}
};
int main()
{
    // freopen(".in","r",stdin),freopen(".out","w",stdout);
    const bool base=1,IO=1;int T;if(!base)T=1;else if(IO)T=read();else ios::sync_with_stdio(0),cin>>T;for(;T--;)Main::main();
    return 0;
}

详细

Test #1:

score: 0
Time Limit Exceeded

input:

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

output:


result: