zoukankan      html  css  js  c++  java
  • [cf739D]Recover a functional graph

    用二元组$A_{i}=(cycle_{i},precycle_{i})$来描述点$i$,则确定$A_{i}$后有解当且仅当:

    设$cnt_{(l,h)}$为$A_{i}=(l,h)$的点数量,则$\forall l\ge 1,l\mid cnt_{(l,0)}$且$0\le j\le h,cnt_{(l,j)}\ge 1$(其中$h=\max_{cnt_{(l,j)}\ge 1}j$)

    (若不存在$cnt_{(l,j)}\ge 1$则记$h=-1$,正确性和构造方式均显然)

    换言之,问题即确定$A_{i}$使得其满足上述条件

    记$cnt'_{(l,h)}$为已确定$A_{i}=(l,h)$的点数量,显然最终$cnt_{(l,h)}\ge cnt'_{(l,h)}$,同时其还满足上述条件

    简单分析,未确定的$A_{i}$中至少要产生$\lceil\frac{cnt'_{l,0}}{l}\rceil \cdot l-cnt'_{(l,0)}$个$(l,0)$和$\forall 1\le j\le \max_{cnt'_{(l,j)}\ge 1}j,\max(1-cnt'_{(l,j)},0)$个$(l,j)$

    另外,若存在$(l,*)$(其中$*$为任意,包括?),则前者的$\lceil\frac{cnt'_{l,0}}{l}\rceil$需要对1取$\max$

    仅根据上述条件,可以对未确定的$A_{i}$和需求建立二分图,如果不存在完美匹配(仅考虑需求)即无解

    注意到需求数超过$n$显然无解,因此这张二分图的点数和边数分别为$o(n)$和$o(n^{2})$,单次二分图匹配复杂度为$o(n^{3})$

    否则,考虑仍未确定的二元组,对其分类讨论:

    1.$(?,?)$或$(?,0)$,直接替换为$(1,0)$即可

    2.$(l,?)$,根据构造总存在$(l,0)$,因此替换为$(l,1)$即可

    3.$(?,h\ge 1)$,显然仅关心于其中最大的$h$,再枚举其所在的$l$即可确定

    虽然可能做$n$次二分图匹配,理论复杂度为$o(n^{4})$,但由于常数较小,可以通过

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define N 305
      4 vector<int>e[N],v[N][N];
      5 vector<pair<int,int> >lim;
      6 int n,m,l[N],h[N],cnt[N][N],mx[N],match[N<<1],vis[N<<1],ans[N];
      7 int read(){
      8     int x=0;
      9     char c=getchar();
     10     while ((c<'0')||(c>'9')){
     11         if (c=='?')return -1;
     12         c=getchar();
     13     }
     14     while ((c>='0')&&(c<='9')){
     15         x=x*10+c-'0';
     16         c=getchar();
     17     }
     18     return x;
     19 }
     20 bool dfs(int k){
     21     if (vis[k])return 0;
     22     vis[k]=1;
     23     for(int i=0;i<e[k].size();i++)
     24         if ((!match[e[k][i]])||(dfs(match[e[k][i]]))){
     25             match[k]=e[k][i],match[e[k][i]]=k;
     26             return 1;
     27         }
     28     return 0;
     29 }
     30 bool calc(){
     31     lim.clear(); 
     32     memset(cnt,0,sizeof(cnt));
     33     memset(mx,-1,sizeof(mx));
     34     memset(vis,0,sizeof(vis));
     35     for(int i=1;i<=n;i++)
     36         if (l[i]>0){
     37             cnt[l[i]][h[i]+1]++;
     38             mx[l[i]]=max(mx[l[i]],h[i]+1);
     39             vis[l[i]]=1;
     40         }
     41     for(int i=1;i<=n;i++){
     42         if (!vis[i])continue;
     43         int s=max((cnt[i][1]+i-1)/i,1)*i-cnt[i][1];
     44         for(int j=0;j<s;j++)lim.push_back(make_pair(i,0));
     45         for(int j=1;j<mx[i];j++)
     46             if (!cnt[i][j+1])lim.push_back(make_pair(i,j));
     47     }
     48     if (lim.size()>n)return 0;
     49     m=lim.size();
     50     for(int i=1;i<=m;i++)e[i].clear();
     51     for(int i=1;i<=n;i++)
     52         if ((l[i]<0)||(h[i]<0)){
     53             for(int j=0;j<lim.size();j++){
     54                 if ((l[i]>0)&&(l[i]!=lim[j].first))continue;
     55                 if ((h[i]>=0)&&(h[i]!=lim[j].second))continue;
     56                 e[j+1].push_back(i+m);
     57             }
     58         }
     59     memset(match,0,sizeof(match));
     60     for(int i=1;i<=m;i++){
     61         memset(vis,0,sizeof(vis));
     62         if (!dfs(i))return 0;
     63     }
     64     for(int i=1;i<=n;i++)
     65         if (match[i+m]){
     66             l[i]=lim[match[i+m]-1].first;
     67             h[i]=lim[match[i+m]-1].second;
     68         }
     69         else{
     70             if ((l[i]<0)&&((h[i]<0)||(!h[i])))l[i]=1,h[i]=0;
     71             if ((l[i]>0)&&(h[i]<0))h[i]=1;
     72             if ((l[i]<0)&&(h[i]>0)){
     73                 for(int j=1;j<=n;j++)
     74                     if (h[i]<mx[j]){
     75                         l[i]=j;
     76                         break;
     77                     }
     78             }
     79         }
     80     for(int i=1;i<=n;i++)
     81         for(int j=0;j<n;j++)v[i][j].clear();
     82     for(int i=1;i<=n;i++)v[l[i]][h[i]].push_back(i);
     83     for(int i=1;i<=n;i++){
     84         for(int j=0;j<v[i][0].size();j++){
     85             if (j%i)ans[v[i][0][j]]=v[i][0][j-1];
     86             else ans[v[i][0][j]]=v[i][0][j+i-1];
     87         }
     88         for(int j=1;j<n;j++)
     89             for(int k=0;k<v[i][j].size();k++)ans[v[i][j][k]]=v[i][j-1][0];
     90     }
     91     for(int i=1;i<n;i++)printf("%d ",ans[i]);
     92     printf("%d\n",ans[n]);
     93     return 1;
     94 }
     95 int main(){
     96     n=read();
     97     int mx=0;
     98     for(int i=1;i<=n;i++){
     99         h[i]=read(),l[i]=read();
    100         if (l[i]<0)mx=max(mx,h[i]);
    101     }
    102     if (!mx){
    103         if (!calc())printf("-1\n");
    104         return 0;
    105     }
    106     for(int i=1;i<=n;i++)
    107         if ((l[i]<0)&&(h[i]==mx)){
    108             bool flag=0;
    109             for(l[i]=1;l[i]<=n;l[i]++)
    110                 if (calc()){
    111                     flag=1;
    112                     break;
    113                 }
    114             if (!flag)printf("-1\n");
    115             return 0;
    116         }
    117     return 0;
    118 } 
    View Code
  • 相关阅读:
    jQuery+Ajax滚屏异步加载数据实现(附源码)
    EasyUI管理后台模板(附源码)
    jQuery带遮罩层弹窗实现(附源码)
    jQuery相册预览简单实现(附源码)
    node.js应用脚手架:koa2、sequelize、mysql
    React demo:express、react-redux、react-router、react-roter-redux、redux-thunk(二)
    React demo:express、react-redux、react-router、react-roter-redux、redux-thunk(一)
    过了一年,再来回顾一下去年到现在,这一年多,作为初级前端小白的坎坷成长历程
    作为一名初级前端小白,写在年初的一些话
    关于jQuery中,animate、slide、fade等动画的连续触发、滞后反复执行的bug的个人解决办法
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/15779824.html
Copyright © 2011-2022 走看看