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个点的树,你从根开始游走,每当你第一次到达一个点时,把这个点的权记为(你已经到过不 ...
随机推荐
- IE浏览器报Promise未定义的错误
背景: 一个vue-cli构建的vue项目,一个使用angular的项目,两个项目在其他浏览器一切正常,但是ie中会报Promise未定义的错误 解决办法: vue的项目: 1. npm insta ...
- VS 附加进程调试
1.在IIS 上新建一个项目,制定目录到 项目根目录. 2.制定IIS上指定 主机名称如: vk.com 3. 修改主机HOST 文件:C:\Windows\System32\drivers\etc ...
- Access-Control-Allow-Methods: OPTIONS & CORS
Access-Control-Allow-Methods: OPTIONS CORS https://stackoverflow.com/questions/20478312/default-valu ...
- NOIP模板
快排 procedure qsort(l,r:longint); var i,j,t,m:longint; begin i:=l; j:=r; m:=a[(i+j) ]; repeat while a ...
- 【题解】HAOI2008硬币购物
1A什么的实在是太开心啦~~洛谷P1450 这道题目主要是考察对于容斥原理的掌握. 首先,注意到如果不存在有关硬币数量的限制而单纯询问方案的总数,就是一个简单的完全背包.这个思路提醒我们:如果能够求出 ...
- [洛谷P2147][SDOI2008]洞穴勘测
题目大意:有$n$个洞穴,$m$条指令,指令有三种 $Connect\;u\;v$:在$u,v$之间连一条边 $Destroy\;u\;v$:切断$u,v$之间的边 $Query\;u\;v$:询问$ ...
- [洛谷P3865]【模板】ST表
题目大意:区间静态最大值 题解:ST表,zkw线段树 ST表: st[i][j]存[i,i+$j^{2}$-1]的最大值,查询时把区间分成两个长度相同的小区间(可重复) #include<cst ...
- MySQL事物机制具备四点:简称ACID操作
MySQL事物机制具备四点:简称ACID操作 1.原子性:要么都做,要么都不做(两条数据(写入和存储)一步未成功,整体回滚) 2.一致性:数据库的状态改变(两条数据(写入和存储)均成功,符合原子性,但 ...
- 洛谷 P4168 [Violet]蒲公英 解题报告
P4168 [Violet]蒲公英 题目背景 亲爱的哥哥: 你在那个城市里面过得好吗? 我在家里面最近很开心呢.昨天晚上奶奶给我讲了那个叫「绝望」的大坏蛋的故事的说!它把人们的房子和田地搞坏,还有好多 ...
- NEYC 2017 游记
day 1: result: sum_rank: 11 school_rank:1 水题在你高估的时候就已经不水了 sum:有个快速乘类似快速幂: int ans=0; ...