p1349星屑幻想
Posted CHADLZX
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了p1349星屑幻想相关的知识,希望对你有一定的参考价值。
这道题的原题目我也不知道是什么。
大致题意是有一个图,有些点的权值已确定,要求你确定其他点的权值使所有边两个点的权值的xor和最小,输出所有点的最终权值,输出有spj;
解法是最小割,由于题目要求的使xor的和最小,那么可以对一位一位考虑;
既然可以这样考虑,那么我们要求的就是在固定了一些点的0/1值的情况下,使xor为1的结果数最少,xor的性质是不相同值为1,相同值为0;
那么就是最小割了,将已确定为0的与s/t连边,将已确定为1de与s/t连边,跑最小割,在残余网络上记录方案;
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<ctime> #include<cstdlib> #include<algorithm> using namespace std; #define LL long long #define up(i,j,n) for(int i=(j);i<=(n);i++) #define FILE "dealing" #define pii pair<int,int> int read(){ int ch=getchar(),x=0,f=1; while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch<=‘9‘&&ch>=‘0‘)x=(x<<1)+(x<<3)+ch-‘0‘,ch=getchar(); return f*x; } const int maxn=10010,inf=100000000; int n,m,k,limit,s=0,t=501; struct node{ int y,next,flow,rev; }e[maxn]; int linkk[maxn],len=0; int f[maxn][33],cnt=0,vis[maxn],c[maxn],z[maxn],X[maxn],Y[maxn],T[maxn]; void insert(int x,int y,int flow){ e[++len].y=y; e[len].flow=flow; e[len].next=linkk[x]; linkk[x]=len; e[len].rev=len+1; e[++len].y=x; e[len].flow=0; e[len].next=linkk[y]; e[len].rev=len-1; linkk[y]=len; } int q[maxn],d[maxn],head,tail; bool makelevel(){ head=tail=0; memset(d,-1,sizeof(d)); q[++tail]=s;d[s]=0;int x; while(++head<=tail){ x=q[head]; for(int i=linkk[x];i;i=e[i].next) if(d[e[i].y]==-1&&e[i].flow)q[++tail]=e[i].y,d[e[i].y]=d[x]+1; } return d[t]!=-1; } int makeflow(int x,int flow){ if(x==t)return flow; if(!flow)return 0; int dis=0,maxflow=0; for(int i=linkk[x];i&&maxflow<flow;i=e[i].next){ if(e[i].flow&&d[e[i].y]==d[x]+1) if(dis=makeflow(e[i].y,min(e[i].flow,flow-maxflow))){ e[e[i].rev].flow+=dis; e[i].flow-=dis; maxflow+=dis; } } if(!maxflow)d[x]=-1; return maxflow; } int dinic(){ int d,ans=0; while(makelevel()) while(d=makeflow(s,inf)) ans+=d; return ans; } void dfs(int x){ vis[x]=1; for(int i=linkk[x];i;i=e[i].next) if(!vis[e[i].y]&&e[i].flow)dfs(e[i].y); } int main(){ n=read(),m=read(); up(i,1,m)X[i]=read(),Y[i]=read(); k=read(); up(i,1,k){ c[i]=read();T[c[i]]=1; int x=z[i]=read(),cnt=0; while(x){ f[c[i]][++cnt]=x%2; x/=2; } limit=max(limit,cnt); } up(i,1,limit){ len=0; memset(linkk,0,sizeof(linkk)); int f1=0,f2=0; up(j,1,k){ if(f[c[j]][i]==0)insert(c[j],t,inf),f1=1; else insert(s,c[j],inf),f2=1; } up(j,1,m)insert(X[j],Y[j],1),insert(Y[j],X[j],1); dinic(); memset(vis,0,sizeof(vis)); dfs(s); if(f1&&f2)up(j,1,n)if(!T[j]&&vis[j])f[j][i]=1; } up(i,1,n){ int x=0; up(j,1,limit)if(f[i][j])x+=(1<<j-1); printf("%d\n",x); } return 0; }
以上是关于p1349星屑幻想的主要内容,如果未能解决你的问题,请参考以下文章