CF #CROC 2016 - Elimination Round D. Robot Rapping Results Report 二分+拓扑排序

题目链接:http://codeforces.com/contest/655/problem/D

大意是给若干对偏序,问最少需要前多少对关系,可以确定所有的大小关系。

解法是二分答案,利用拓扑排序看是否所有关系被唯一确定。即任意一次只能有1个元素入度为0入队。

 1 #include <iostream>
 2 #include <vector>
 3 #include <algorithm>
 4 #include <string>
 5 #include <string.h>
 6 #include <stdio.h>
 7 #include <math.h>
 8 #include <queue>
 9 #include <stack>
10 #include <map>
11 #include <set>
12
13 using namespace std;
14
15
16 const int N=123456;
17
18 struct Edge {
19     int to,next;
20     Edge() {}
21     Edge(int _to,int _nxt):to(_to),next(_nxt) {}
22 } edge[N<<2];
23 int idx=1,head[N];
24 void addedge(int u,int v) {
25     edge[++idx]=Edge(v,head[u]);
26     head[u]=idx;
27 }
28 int in[N],que[N];
29
30 int a[N],b[N];
31
32 bool topoSort(int n,int mid){
33     idx=1;memset(head,0,sizeof head);
34     memset(in,0,sizeof in);
35     for (int i=1;i<=mid;i++) {
36         addedge(a[i],b[i]);
37         in[b[i]]++;
38     }
39     int tail=0;
40     for (int i=1;i<=n;i++)
41         if (in[i]==0)
42             que[tail++]=i;
43     if (tail>1) return false;
44     for (int i=0;i<tail;i++){
45         int cnt=0;
46         for (int k=head[que[i]];k;k=edge[k].next){
47             int v=edge[k].to;
48             in[v]--;
49             if (in[v]==0){
50                 cnt++;
51                 if (cnt>1) return false;
52                 que[tail++]=v;
53             }
54         }
55     }
56     return true;
57 }
58
59
60 int main() {
61     int n,m;
62     scanf("%d %d",&n,&m);
63     for (int i=1;i<=m;i++) {
64         scanf("%d %d",a+i,b+i);
65     }
66     int low=1,high=m,ret=-1;
67     while (low<=high) {
68         int mid=(low+high)>>1;
69         if (topoSort(n,mid)) {
70             ret=mid;
71             high=mid-1;
72         }
73         else
74             low=mid+1;
75     }
76     printf("%d\n",ret);
77     return 0;
78 }

时间: 2024-11-12 11:08:57

CF #CROC 2016 - Elimination Round D. Robot Rapping Results Report 二分+拓扑排序的相关文章

codeforces 655D D. Robot Rapping Results Report(拓扑排序+拓扑序记录)

题目链接: D. Robot Rapping Results Report time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output While Farmer John rebuilds his farm in an unfamiliar portion of Bovinia, Bessie is out trying some alt

CROC 2016 - Elimination Round (Rated Unofficial Edition) D. Robot Rapping Results Report 拓扑排序+二分

题目链接: http://www.codeforces.com/contest/655/problem/D 题意: 题目是要求前k个场次就能确定唯一的拓扑序,求满足条件的最小k. 题解: 二分k的取值,做拓扑排序的时候只要每次只有一个元素没有前驱就可以唯一了. #include<iostream> #include<cstring> #include<cstdio> #include<vector> #include<queue> #includ

CROC 2016 - Elimination Round Mischievous Mess Makers

这个题的意思是给你一个自然数序列1-n, 然后让你交换其中的一些数使得新序列的逆序对个数最大,  直接推公式即可, 代码如下: #include <bits/stdc++.h> using namespace std; typedef long long LL; int main() { int n, k; scanf("%d%d", &n, &k); LL pa = min(n/2, k); LL res1 = (n-2*pa)*pa; LL res2 =

CROC 2016 - Elimination Round Enduring Exodus

这道题的意思是给你一串01序列, 0代表空房子, 1代表非空的房子, 农夫约翰和他的K个牛要住进空房子里面,i房子和j房子的距离是|j-i| 问农夫约翰和他的最远的牛的最小值是多少? 我们可以枚举牛的起点, 算出终点然后二分农夫约翰的位置, 代码如下: #include <bits/stdc++.h> using namespace std; int a[100000 + 100], na; int Binary(int num) { //找出<=num的最后一个位置 int l=0,

CROC 2016 - Elimination Round (Rated Unofficial Edition) E - Intellectual Inquiry dp

E - Intellectual Inquiry 思路:我自己YY了一个算本质不同子序列的方法, 发现和网上都不一样. 我们从每个点出发向其后面第一个a, b, c, d ...连一条边,那么总的不同子序列就是从0号点出发能走出多少条 不同点的路径. dp[ i ]表示是到 i 这个点的不同路径数, 构成的图显然是个DAG,把这个dp出来就好啦.最后补 n个就是贪贪心. 网上的另外两种方法. dp[ i ] 表示[1, i] 的字符串有多少不同子序列. dp[ i ] = dp[i - 1] *

codeforces 645D Robot Rapping Results Report

二分一下答案check即可.(拓扑排序) #include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<algorithm> #define maxv 100500 #define maxe 200500 using namespace std; int n,m,nume=0,g[maxv],x[maxv],y[maxv],d[maxv],rank[m

8VC Venture Cup 2016 - Elimination Round

在家补补题   模拟 A - Robot Sequence #include <bits/stdc++.h> char str[202]; void move(int &x, int &y, char ch) { if (ch == 'U') x--; if (ch == 'D') x++; if (ch == 'L') y--; if (ch == 'R') y++; } int main(void) { int n; scanf ("%d", &

codeforces 8VC Venture Cup 2016 - Elimination Round C. Lieges of Legendre

C. Lieges of Legendre 题意:给n,m表示有n个为2的倍数,m个为3的倍数:问这n+m个数不重复时的最大值 最小为多少? 数据:(0 ≤ n, m ≤ 1 000 000, n + m > 0) ps:很水的题,主要是策略: 思路:由于里面每隔6就会重复一次,不好直接模拟,并且模拟的效率很低,那就二分吧!二分即上界为2单独的最大倍数与3单独时的最大倍数之和,下界为前面二者的max;之后利用判断是否mid/2 >= n && mid/3 >= m &am

8VC Venture Cup 2016 - Elimination Round E. Simple Skewness(枚举+三分)

题目链接:点击打开链接 题意:给你n个数, 要求选若干个数, 使得这些数的平均数减去中位数尽量大. 思路:由于该题没有顺序问题, 排好序之后我们可以枚举中位数, 可以证明, 奇数个数一定比偶数优,然后三分中位数左右区间长度x(数的个数), 在中位数的右边选最大的x个数, 在左边也选最大的x个, 这样, 随着区间长度的增加, 平均数将先增大后减小, 或者一直减小,或者一直增大. 为什么呢? 假设第一次的区间长度是1, 那么我们选择了两边最大的两个数, 假设他们加起来取平均大于中位数, 那么对答案有