[杂题] Codeforces 739D Round #381 (Div. 1) D. Recover a functional graph

来源:互联网 发布:阿里云 驾照识别 编辑:程序博客网 时间:2024/06/15 21:19

Let’s think what has to hold after we put numbers in place of question
marks:

  • number of vertices with precycle = 0 and cycle = y should be divisible by y.
  • if there exists a vertex with precycle = x > 0 and cycle = y, then there should also exist a vertex with precycle = x - 1 and cycle = y.

这个直接用最大流跑个匹配
但是要注意特殊讨论最长的那一条 所以要跑n次最大流

#include<cstdio>#include<cstdlib>#include<algorithm>#include<cstring>#include<cmath>#include<vector>#define pb push_back#define cl(x) memset(x,0,sizeof(x))using namespace std;inline char nc(){  static char buf[100000],*p1=buf,*p2=buf;  return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}inline void read(int &x){  char c=nc(),b=1;  for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; else if (c=='?') return void(x=-1);  for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;}namespace D{  const int N=200005;  const int M=N<<2;  struct edge{    int u,v,f,next;  }G[M<<1];  int head[N],inum=1;  inline void add(int u,int v,int f,int p){    G[p].u=u; G[p].v=v; G[p].f=f; G[p].next=head[u]; head[u]=p;  }  inline void link(int u,int v,int f){    add(u,v,f,++inum),add(v,u,0,++inum);  }#define V G[p].v  int S,T;  int dis[N],Q[N],l,r;  inline bool bfs(){    l=r=-1; for (int i=1;i<=T;i++) dis[i]=-1;    Q[++r]=S; dis[S]=0;    while (l<r){      int u=Q[++l];      for (int p=head[u];p;p=G[p].next)    if (G[p].f && dis[V]==-1){      dis[V]=dis[u]+1; Q[++r]=V;      if (V==T) return 1;    }    }    return 0;  }  int cur[N];  inline int dfs(int u,int flow){    if (u==T) return flow;    int used=0;    for (int p=cur[u];p;p=G[p].next){      cur[u]=p;      if (dis[V]==dis[u]+1 && G[p].f){    int d=dfs(V,min(flow-used,G[p].f));    G[p].f-=d; G[p^1].f+=d;    used+=d; if (used==flow) break;      }    }    if (!used) dis[u]=-1;    return used;  }  inline int Dinic(){    int ans=0;    while (bfs()){      memcpy(cur,head,sizeof(int)*(T+5));      ans+=dfs(S,1<<30);    }    return ans;  }}const int N=305;int n,a[N],b[N];int maxa;int vst[N][N],maxl[N];int cnt[N];int x[N],y[N],tot;int to[N];int idx[N][N];vector<int> cir[N];inline void Print(int c){  using namespace D;  for (int p=2;p<=inum;p+=2)    if (G[p].u!=S && G[p].v!=T && G[p].f==0)      a[G[p].u]=x[V-n],b[G[p].u]=y[V-n];  for (int i=1;i<=n;i++){    if (a[i]==-1 && b[i]==-1)      a[i]=0,b[i]=1;    else if (a[i]>0 && b[i]==-1)      b[i]=c;    else if (a[i]==-1 && b[i]!=-1)      a[i]=1;    else if (a[i]==0 && b[i]==-1)      b[i]=1;    idx[a[i]][b[i]]=i;    if (a[i]==0)      cir[b[i]].pb(i);  }  for (int i=1;i<=n;i++)    for (int j=0;j<cir[i].size();j+=i)      for (int k=0;k<i;k++)    to[cir[i][j+k]]=cir[i][j+(k+1)%i];  for (int i=1;i<=n;i++)    if (a[i]!=0)      to[i]=idx[a[i]-1][b[i]];  for (int i=1;i<=n;i++)    printf("%d ",to[i]);  exit(0);}int must[N];int main(){  freopen("catastrophe.in","r",stdin);  freopen("catastrophe.out","w",stdout);  read(n); int k=0;  for (int i=1;i<=n;i++){    read(a[i]),read(b[i]);    if (a[i]>0 && b[i]==-1) if (!k || a[k]<a[i]) k=i;    if (a[i]>0 && b[i]!=-1) vst[b[i]][a[i]]++,maxl[b[i]]=max(maxl[b[i]],a[i]);    if (a[i]==0 && b[i]!=-1) cnt[b[i]]++;    if (b[i]!=-1) must[b[i]]++;  }  for (int i=1;i<=n;i++){    using namespace D;    int tmp;    if (k){      b[k]=i,vst[i][a[k]]++; must[i]++;      tmp=maxl[i];      maxl[i]=max(maxl[i],a[k]);    }    tot=0;    for (int i=1;i<=n;i++)      if (must[i] && (cnt[i]==0 || cnt[i]%i!=0))    ++tot,x[tot]=0,y[tot]=i;    for (int i=1;i<=n;i++)      for (int j=1;j<=maxl[i];j++)    if (!vst[i][j])      ++tot,x[tot]=j,y[tot]=i;    S=n+tot+1;    T=n+tot+2; int flow=0;    for (int i=1;i<=tot;i++)      if (x[i]==0)    link(n+i,T,y[i]-cnt[y[i]]%y[i]),flow+=y[i]-cnt[y[i]]%y[i];      else    link(n+i,T,1),flow++;    for (int i=1;i<=n;i++)      if (a[i]==-1 || b[i]==-1){    link(S,i,1);    for (int j=1;j<=tot;j++)      if ((a[i]==-1 || a[i]==x[j]) && (b[i]==-1 || b[i]==y[j]))        link(i,n+j,1);      }    if (Dinic()==flow)      Print(i);    cl(head); inum=1;    if (k)      b[k]=-1,vst[i][a[k]]--,maxl[i]=tmp,must[i]--;  }  printf("-1\n");  return 0;}
原创粉丝点击