社区讨论

g 求条

学术版参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@mlme1dk2
此快照首次捕获于
2026/02/14 22:04
5 天前
此快照最后确认于
2026/02/18 20:10
18 小时前
查看原帖
到处爆 assert 不知道为什么。
CPP
#include<bits/stdc++.h>
#define endl '\n'
#define M 800006
using namespace std;
struct MF_Graph { //by dyc2022
	int head[M],cnt,s,t,now[M],dep[M];
	MF_Graph() {cnt=2;}
	struct Edge {int to,next,w;} E[3000006];
	void addedge(int u,int v,int w) {E[cnt]={v,head[u],w},head[u]=cnt++;}
	void addflow(int u,int v,int w) {addedge(u,v,w),addedge(v,u,0);}
	int bfs()
	{
	    queue<int> q;
	    memset(dep,-1,sizeof(dep));
	    dep[s]=0,now[s]=head[s],q.push(s);
	    while(q.size())
	    {
	        int u=q.front(); q.pop();
	        for(int i=head[u],v,w;i;i=E[i].next)
	        {
	            v=E[i].to,w=E[i].w;
	            if(dep[v]==-1&&w>0)
	            	{dep[v]=dep[u]+1,now[v]=head[v],q.push(v); if(v==t)return 1;}
	        }
	    }
	    return 0;
	}
	int dfs(int u,int fl)
	{
	    if(u==t)return fl;
	    int ret=0;
	    for(int i=now[u],v,w;i&&fl>0;i=E[i].next)
	    {
	        v=E[i].to,w=E[i].w,now[u]=i;
	        if(dep[v]==dep[u]+1&&w>0)
	        {
	            int tmp=dfs(v,min(fl,w));
	            if(!tmp)dep[v]=-1; E[i].w-=tmp,E[i^1].w+=tmp,fl-=tmp,ret+=tmp;
	        }
	    }
	    return ret;
	}
	int getflow() {int ret=0; while(bfs())ret+=dfs(s,1e9); return ret;}
} G;
int n,m,A,B,a[306][306],col[M],eid[M],vis[M],mt[M],ans[M];
struct Edge {int u,v;} E[M];
char ch[M];
inline int id(int x,int y) {return (x-1)*n+y;}
vector<int> yG[M],bG[M];
void color(int u)
{
    for(int v:yG[u])
        if(col[v]==-1)col[v]=col[u]^1,color(v);
        else assert(col[v]^col[u]);
}
void dfs(int u) {vis[u]=1; for(int v:bG[u])if(!vis[v])dfs(v);}
main()
{
    scanf("%d%d%d",&n,&A,&B);
    for(int i=1;i<=n;i++)
    {
        scanf("%s",ch+1);
        for(int j=1;j<=n;j++)a[i][j]=(ch[j]=='#');
    }
    int dx[]={A,B,B,A};
    int dy[]={B,A,-A,-B};
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)if(!a[i][j])
    {
        for(int k=0;k<4;k++)
        {
            int tx=i+dx[k],ty=j+dy[k];
            if(tx<1||tx>n||ty<1||ty>n||a[tx][ty])continue;
            E[++m]={id(i,j),id(tx,ty)};
            yG[id(i,j)].push_back(id(tx,ty));
            yG[id(tx,ty)].push_back(id(i,j));
        }
    }
    memset(col,-1,sizeof(col));
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)if(col[id(i,j)]==-1&&!a[i][j])
            col[id(i,j)]=0,color(id(i,j));
    G.s=n+1,G.t=n+2;
    for(int i=1;i<=n*n;i++)
        if(col[i]==0)G.addflow(G.s,i,1);
        else if(col[i]==1)G.addflow(i,G.t,1);
    for(int i=1;i<=m;i++)
    {
        int u=E[i].u,v=E[i].v;
        if(col[u])swap(u,v);
        assert(col[u]==0&&col[v]==1);
        G.addflow(u,v,1),eid[i]=G.cnt-1;
    }
    int mxfl;
    cerr<<(mxfl=G.getflow())<<endl;
    for(int i=1;i<=m;i++)
    {
        int u=E[i].u,v=E[i].v;
        if(col[u])swap(u,v);
        if(G.E[eid[i]].w)bG[u].push_back(v),mt[v]=1;
        else bG[v].push_back(u);
    }
    for(int i=1;i<=n*n;i++)
        if(col[i]==1&&!mt[i])dfs(i);
    int ccc=0;
    for(int i=1;i<=n*n;i++)
        if((col[i]==0&&!vis[i])||(col[i]==1&&vis[i]))ans[i]=1;
        else if(col[i]==0||col[i]==1)ccc++;
    cerr<<ccc<<endl;
    //assert(ccc==mxfl);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
    {
        if(a[i][j])putchar('#');
        else if(ans[id(i,j)])putchar('o');
        else putchar('.');
        if(j==n)putchar(10);
    }
    return 0;
}
//最小点覆盖,就是左边遍历到的结点集合,和右边没遍历到的结点集合的并集。

回复

0 条回复,欢迎继续交流。

正在加载回复...