这题码量好大……

首先思考如何构造,不难找到一下两个条件

1. 在长度为i的环上的点一定是i的倍数个

2. 到达长度i的环的点集距离一定是连续的

第一个条件是很好搞的,关键是第二个条件。

因为存在着x ?这样的点,我们不知道到达环长度为i的点precycle能会连续延伸

但是观察可知,我们只要找出x ?类点中x最大的点xmax,穷举最终走到环的长度,

这样其他比xmax小的x ?点肯定都接到这个环上最有可能出解,那么到达每种环长度的precycle界限就确定了

这样我们就可以建图匹配来判定是否可行了,一侧条件一侧点连边看是否满流即可。

找出条件点流向的点,我们就能确定这些点的?是什么了

那么还有些点没用到应该怎么替换?呢

? ?的点直接构造一元环,x ?接在可行处,? x直接零?为1

而我们确定所有点的precycle和cycle后,是很容易构造最终出边的:

只要把环建好,其他在环上一个点下挂成一个简单树形即可

思路不难,写起来比较麻烦

 #include<bits/stdc++.h>
#define mp make_pair using namespace std;
const int inf=;
struct way{int po,next,flow;} e[];
pair<int,int> q[];
int len,n,m,t,mx,pre[],numh[],cur[],h[],d[],p[];
int w[][],hs[][],a[],b[],r[],ans[];
vector<int> g[][];
string s;
bool v[]; void add(int x,int y,int f)
{
e[++len].po=y;
e[len].flow=f;
e[len].next=p[x];
p[x]=len;
}
void build(int x, int y, int f)
{
add(x,y,f);
add(y,x,);
} int sap()
{
memset(h,,sizeof(h));
memset(numh,,sizeof(numh));
numh[]=t+;
for (int i=; i<=t; i++) cur[i]=p[i];
int j,u=,s=,neck=inf;
while (h[]<t+)
{
d[u]=neck;
bool ch=;
for (int i=cur[u]; i!=-; i=e[i].next)
{
j=e[i].po;
if (e[i].flow>&&h[u]==h[j]+)
{
neck=min(neck,e[i].flow);
cur[u]=i;
pre[j]=u; u=j;
if (u==t)
{
s+=neck;
while (u)
{
u=pre[u];
j=cur[u];
e[j].flow-=neck;
e[j^].flow+=neck;
}
neck=inf;
}
ch=;
break;
}
}
if (ch)
{
if (--numh[h[u]]==) return s;
int q=-,tmp=t;
for (int i=p[u]; i!=-; i=e[i].next)
{
j=e[i].po;
if (e[i].flow&&h[j]<tmp)
{
tmp=h[j];
q=i;
}
}
cur[u]=q; h[u]=tmp+;
numh[h[u]]++;
if (u)
{
u=pre[u];
neck=d[u];
}
}
}
return s;
} bool check()
{
t=n; len=-;
memset(p,,sizeof(p));
memset(v,,sizeof(v));
memset(hs,,sizeof(hs));
for (int i=; i<=n; i++) v[b[i]]=;
int can=;
for (int i=; i<=n; i++)
if (v[i])
{
int x=;
if (!w[i][]) x=i;
else x=i-(w[i][]-)%i-;
if (x)
{
hs[i][]=++t; q[t]=mp(i,);
build(,t,x); can+=x;
}
for (int j=; j<r[i]; j++)
if (!w[i][j])
{
hs[i][j]=++t; q[t]=mp(i,j);
build(,t,); can++;
}
}
for (int i=; i<=n; i++)
{
if (a[i]<n+&&b[i]<n+) continue;
if (a[i]==n+&&b[i]==n+)
{
for (int j=n+; j<=t; j++)
build(j,i,);
}
else if (b[i]==n+)
{
for (int j=; j<=n; j++)
if (hs[j][a[i]]) build(hs[j][a[i]],i,);
}
else if (a[i]==n+)
{
for (int j=; j<r[b[i]]; j++)
if (hs[b[i]][j]) build(hs[b[i]][j],i,);
}
build(i,t+,);
}
t++;
if (sap()<can) return ; else return ;
} void print()
{
for (int i=n+; i<t; i++)
for (int j=p[i]; j>-; j=e[j].next)
{
int x=e[j].po;
if (x&&x<=n&&!e[j].flow)
{
a[x]=q[i].second;
b[x]=q[i].first;
}
}
// for (int i=1; i<=n; i++) cout <<a[i]<<" "<<b[i]<<endl;
for (int i=; i<=n; i++)
if (a[i]==n+&&b[i]==n+) {a[i]=; b[i]=;}
else if (a[i]==n+) {a[i]=;}
else if (b[i]==n+)
{
for (int j=; j<=n; j++)
if (r[j]>=a[i]) {b[i]=j; break;}
}
for (int i=; i<=n; i++)
g[b[i]][a[i]].push_back(i);
for (int i=; i<=n; i++)
{
for (int j=; j<g[i][].size(); j+=i)
{
for (int k=j; k<j+i-; k++) ans[g[i][][k]]=g[i][][k+];
ans[g[i][][j+i-]]=g[i][][j];
}
for (int j=; j<=n; j++)
for (int k=; k<g[i][j].size(); k++)
ans[g[i][j][k]]=g[i][j-][];
}
for (int i=; i<=n; i++) printf("%d ",ans[i]);
} int main()
{
scanf("%d\n",&n);
mx=;
for (int i=; i<=n; i++)
{
getline(cin,s);
int l=s.length(),j;
for (j=; j<l; j++)
{
if (s[j]=='?') a[i]=n+;
else if (s[j]==' ') break;
else a[i]=a[i]*+s[j]-'';
}
j++;
for (; j<l; j++)
{
if (s[j]=='?') b[i]=n+;
else if (s[j]==' ') break;
else b[i]=b[i]*+s[j]-'';
}
if (a[i]<n+&&b[i]==n+)
{
if (a[mx]<a[i]) mx=i;
}
else w[b[i]][a[i]]++;
}
for (int i=; i<=n; i++)
for (int j=n; j; j--)
if (w[i][j]) {r[i]=j; break;}
bool ff=;
for (int i=; i<=n; i++)
{
int pr=r[i];
if (r[i]<a[mx])
{
r[i]=a[mx];
b[mx]=i;
}
if (check()) {ff=;break;}
b[mx]=n+; r[i]=pr;
}
if (!ff) puts("-1"); else print();
return ;
}

codeforces 739D的更多相关文章

  1. Codeforces 739D - Recover a functional graph(二分图匹配)

    Codeforces 题面传送门 & 洛谷题面传送门 首先假设我们已经填好了所有问号处的值怎样判断是否存在一个合法的构造方案,显然对于一种方案能够构造出合法的基环内向森林当且仅当: \(\fo ...

  2. python爬虫学习(5) —— 扒一下codeforces题面

    上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...

  3. 【Codeforces 738D】Sea Battle(贪心)

    http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...

  4. 【Codeforces 738C】Road to Cinema

    http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...

  5. 【Codeforces 738A】Interview with Oleg

    http://codeforces.com/contest/738/problem/A Polycarp has interviewed Oleg and has written the interv ...

  6. CodeForces - 662A Gambling Nim

    http://codeforces.com/problemset/problem/662/A 题目大意: 给定n(n <= 500000)张卡片,每张卡片的两个面都写有数字,每个面都有0.5的概 ...

  7. CodeForces - 274B Zero Tree

    http://codeforces.com/problemset/problem/274/B 题目大意: 给定你一颗树,每个点上有权值. 现在你每次取出这颗树的一颗子树(即点集和边集均是原图的子集的连 ...

  8. CodeForces - 261B Maxim and Restaurant

    http://codeforces.com/problemset/problem/261/B 题目大意:给定n个数a1-an(n<=50,ai<=50),随机打乱后,记Si=a1+a2+a ...

  9. CodeForces - 696B Puzzles

    http://codeforces.com/problemset/problem/696/B 题目大意: 这是一颗有n个点的树,你从根开始游走,每当你第一次到达一个点时,把这个点的权记为(你已经到过不 ...

随机推荐

  1. Xshell出现要继续使用此程序必须应用到最新的更新或使用新版本

    资源可以用,但是安装完成后启动会报错:“要继续使用此程序,您必须应用最新的更新或使用新版本” 解决办法先修改你电脑时间为前一年(2017 1月),然后就可以打开xshell了,打开后"工具& ...

  2. 算法(10)Subarray Sum Equals K

    题目:在数组中找到一个子数组,让子数组的和是k. 思路:先发发牢骚,这两天做题是卡到不行哇,前一个题折腾了三天,这个题上午又被卡住,一气之下,中午睡觉,下午去了趟公司,竟然把namespace和cgr ...

  3. URL大小写敏感之谜

    URL其实就是我们浏览器地址栏的地址,一般由三部分组成: 协议名称,一般就是http 域名,也就是主机名 资源路径 如链接:http://www.w3school.com.cn/js/js_obj_r ...

  4. Sigar应用

    sigar是一个用于获取底层硬件信息比如:CPU,内存,硬盘,网络等等信息的库.其官网如下: https://support.hyperic.com/display/SIGAR/Home   出于项目 ...

  5. maven release版本重复上传error

    A couple things I can think of: user credentials are wrong url to server is wrong user does not have ...

  6. Oracle解决索引碎片功能

    我们开始时向一个空的带索引的表中插入大量数据后,是不会产生碎片问题的,但是,数据库经过很长一段时间的增删改查后,难免会出现碎片问题,影响数据库的性能,Oracle对于这一问题有自己的解决方案. 下面介 ...

  7. struts标签中的select

    <!-- Struts下拉列表标签: name="deptId" 下拉列表标签的名称(服务器根据这个名称获取选择的项的实际的值value值) headerKey 默认选择项的 ...

  8. mac 倍速播放

    Mac的倍速播放,使用工具播放是quick time player,使用方式是,按住 “option” + “>>” 即可调整倍数:

  9. BZOJ4524 CQOI2016伪光滑数(堆)

    对于每个质数求出其作为最大质因子时最多能有几个质因子,开始时将这些ak1~akmaxk扔进堆.考虑构造方案,使得每次取出最大值后,最大质因子.质因子数均与其相同且恰好比它小的数都在堆里.类似暴搜,对于 ...

  10. 从统计学statistics的观点看概率分布

    已知数据x,希望得到未知label y,即得到映射x-->y: 几个概念: 1)p(x): data distribution 数据分布 2)p(y): prior distribution 先 ...