codeforces 739D
这题码量好大……
首先思考如何构造,不难找到一下两个条件
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的更多相关文章
- Codeforces 739D - Recover a functional graph(二分图匹配)
Codeforces 题面传送门 & 洛谷题面传送门 首先假设我们已经填好了所有问号处的值怎样判断是否存在一个合法的构造方案,显然对于一种方案能够构造出合法的基环内向森林当且仅当: \(\fo ...
- python爬虫学习(5) —— 扒一下codeforces题面
上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...
- 【Codeforces 738D】Sea Battle(贪心)
http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...
- 【Codeforces 738C】Road to Cinema
http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...
- 【Codeforces 738A】Interview with Oleg
http://codeforces.com/contest/738/problem/A Polycarp has interviewed Oleg and has written the interv ...
- CodeForces - 662A Gambling Nim
http://codeforces.com/problemset/problem/662/A 题目大意: 给定n(n <= 500000)张卡片,每张卡片的两个面都写有数字,每个面都有0.5的概 ...
- CodeForces - 274B Zero Tree
http://codeforces.com/problemset/problem/274/B 题目大意: 给定你一颗树,每个点上有权值. 现在你每次取出这颗树的一颗子树(即点集和边集均是原图的子集的连 ...
- CodeForces - 261B Maxim and Restaurant
http://codeforces.com/problemset/problem/261/B 题目大意:给定n个数a1-an(n<=50,ai<=50),随机打乱后,记Si=a1+a2+a ...
- CodeForces - 696B Puzzles
http://codeforces.com/problemset/problem/696/B 题目大意: 这是一颗有n个点的树,你从根开始游走,每当你第一次到达一个点时,把这个点的权记为(你已经到过不 ...
随机推荐
- 【bzoj2325】[ZJOI2011]道馆之战 树链剖分+线段树区间合并
题目描述 给定一棵树,每个节点有上下两个格子,每个格子的状态为能走或不能走.m次操作,每次修改一个节点的状态,或询问:把一条路径上的所有格子拼起来形成一个宽度为2的长方形,从起点端两个格子的任意一个开 ...
- 用JavaScript实现一个简单的树结构
数据源用数组混json结构,实现了基本的功能.效率一般,跟 dhtree 梅花雪树对比了下,都差不多. (ps感觉比dhtree快点,跟梅花雪树差不多,个人测试) 这个实现树的原理是根据json,不断 ...
- 深入理解Java虚拟机—内存管理机制
前面说过了类的加载机制,里面讲到了类的初始化中时用到了一部分内存管理的知识,这里让我们来看下Java虚拟机是如何管理内存的. 先让我们来看张图 有些文章中对线程隔离区还称之为线程独占区,其实是一个意思 ...
- POJ1511:Invitation Cards(最短路)
Invitation Cards Time Limit: 8000MS Memory Limit: 262144K Total Submissions: 34743 Accepted: 114 ...
- codeforces 1060 C
https://codeforces.com/contest/1060/problem/C 题意:给你一个长度为n的数列a和长度为m的数列b,定义c(i,j)=ai*bj,得到c矩阵,给定值x,求c矩 ...
- css和javascript中图片路径的不同
之前在写前端代码时,在图片路径的设置那里经常会遇到一个问题.比方说,我 (1)在根目录下面新建了个"images"文夹,里面放了张图片top.gif (2)在根目录下另外新建了两个 ...
- Spring - IoC(2): 属性注入 & 构造注入
依赖注入是指程序运行过程中,如果需要另外的对象协作(访问它的属性或调用它的方法)时,无须在代码中创建被调用者,而是依赖于外部容器的注入. 属性注入(Setter Injection) 属性注入是指 I ...
- hdu 1175 连连看 (深搜)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1175 题目大意:如果某两个相同的棋子,可以通过一条线连起来(这条线不能经过其它棋子)这样的两个棋子可以 ...
- Linux 格式化磁盘命令mkfs
linux格式化磁盘命令 mkfs 指令:mkfs 使用权限 : 超级使用者 使用方式 : mkfs [-V] [-t fstype] [fs-options] f ...
- LeetCode 151 reverse word in a string
Given an input string, reverse the string word by word. For example, Given s = "the sky is blue ...