HDU5638 / BestCoder Round #74 (div.1) 1003 Toposort 线段树+拓扑排序
Toposort
给出nn个点mm条边的有向无环图. 要求删掉恰好kk条边使得字典序最小的拓扑序列尽可能小.
输入包含多组数据. 第一行有一个整数TT, 表示测试数据组数. 对于每组数据: 第一行包含3个整数nn, mm和kk (1 \le n \le 100000, 0 \le k \le m \le 200000)(1≤n≤100000,0≤k≤m≤200000), 表示图中结点数目, 图中边的数目以及要删的边数. 接下来mm行, 每行包含两个整数u_iui and v_ivi, 表示存在一条u_iui到v_ivi的有向边 (1 \le u_i, v_i \le n)(1≤ui,vi≤n). 输入保证给定的图是一个DAG. 输入数据中nn的和不超过10^6106. 输入数据中mm的和不超过2 \cdot 10^62⋅106.
对于每组数据, 输出一个整数S = (\displaystyle\sum_{i=1}^{n}{i\cdot p_i}) \text{ mod } (10^9 + 7)S=(i=1∑ni⋅pi) mod (109+7), 其中p_{1}, p_{2}, ..., p_{n}p1,p2,...,pn是字典序最小的那个拓扑序列.
3
4 2 0
1 2
1 3
4 5 1
2 1
3 1
4 1
2 3
2 4
4 4 2
1 2
2 3
3 4
1 4
30
27
30
题解:
参考下普通的用堆维护求字典序最小拓扑序, 用某种数据结构维护入度小于等于kk的所有点, 每次找出编号最小的, 并相应的减少kk即可.
这个数据结构可以用线段树, 建立一个线段树每个节点[l,r][l,r]维护编号从ll到rr的所有节点的最小入度, 查询的时候只需要在线段树上二分, 找到最小的xx满足入度小于等于kk.
复杂度O((n+m)\log n)O((n+m)logn)
/// #include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include<vector>
using namespace std;
using namespace std ;
typedef long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define pb push_back
const int N=+;
const int mod = 1e9+;
const int inf = 1e9+; int ind[N],head[N],t,n,m,K,vis[N];
vector<int > ans;
vector<int >G[N];
struct ss {
int l,r,sum,index;
}tr[N*];
struct sss {
int to,next;
}e[N*];
void init() {
t=;mem(head);mem(ind);ans.clear();mem(vis);
for(int i=;i<N;i++)G[i].clear();
}
void add(int u,int v) {e[t].to=v;e[t].next=head[u];head[u]=t++;}
void build(int k,int s,int t) {
tr[k].l=s;tr[k].r=t;
if(s==t) {
tr[k].sum=ind[s];
tr[k].index=s;
return ;
}
int mid=(s+t)>>;
build(k<<,s,mid);
build(k<<|,mid+,t);
tr[k].sum=min(tr[k<<].sum,tr[k<<|].sum);
}
int ask(int k,int s,int t,int c) {
int ret;
if(tr[k].l==tr[k].r&&tr[k].l==s) {
return tr[k].index;
}
int mid=(tr[k].l+tr[k].r)>>;
if(tr[k<<].sum<=c) {
ret=ask(k<<,s,mid,c);
}
else {
ret=ask(k<<|,mid+,t,c);
}
return ret;
}
void update(int k,int x,int c) {
if(tr[k].l==tr[k].r&&tr[k].l==x) {
tr[k].sum+=c;
return ;
}
int mid=(tr[k].l+tr[k].r)>>;
if(x<=mid) update(k<<,x,c);
else update(k<<|,x,c);
tr[k].sum=min(tr[k<<].sum,tr[k<<|].sum);
}
int main() {
int T;
scanf("%d",&T);
while(T--) {
scanf("%d%d%d",&n,&m,&K);
init();int u,v,check;
for( int i=;i<=m;i++) {
scanf("%d%d",&u,&v);
ind[v]++;
G[u].pb(v);
}
build(,,n);
for(int i=;i<=n;i++) {
check=ask(,,n,K);
ans.pb(check);
K-=ind[check];
update(,check,inf);
for(int j=;j<G[check].size();j++) {
update(,G[check][j],-);
ind[G[check][j]]--;
}
}
ll A = ;
for(int i=;i<ans.size();i++) {
A=(A+1ll*(i+)*ans[i])%mod;
}
printf("%I64d\n",A);
}
return ;
}
HDU5638 / BestCoder Round #74 (div.1) 1003 Toposort 线段树+拓扑排序的更多相关文章
- hdu5635 BestCoder Round #74 (div.2)
LCP Array Accepts: 131 Submissions: 1352 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 13 ...
- hdu 5636 搜索 BestCoder Round #74 (div.2)
Shortest Path Accepts: 40 Submissions: 610 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: ...
- DP BestCoder Round #50 (div.2) 1003 The mook jong
题目传送门 /* DP:这题赤裸裸的dp,dp[i][1/0]表示第i块板放木桩和不放木桩的方案数.状态转移方程: dp[i][1] = dp[i-3][1] + dp[i-3][0] + 1; dp ...
- Codeforces Round #603 (Div. 2) E. Editor 线段树
E. Editor The development of a text editor is a hard problem. You need to implement an extra module ...
- Codeforces Round #660 (Div. 2) Captain Flint and Treasure 拓扑排序(按照出度、入读两边拓扑排序)
题目链接:Captain Flint and Treasure 题意: 一种操作为 选一个下标 使得ans+=a[i] 且 把a[b[i]]+a[i] 要求每个下标都进行一种这样的操作,问怎么样的 ...
- BestCoder Round #74 (div.2)
组合 1001 LCP Array 第一题就小难,出题的好像是浙大的大牛? 找到一个规律:a[i] = x, s[i..i+x]都想同.a[i] = a[i+1] + 1 (a[i] > 0), ...
- BestCoder Round #81 (div.2) 1003 String
题目地址:http://bestcoder.hdu.edu.cn/contests/contest_showproblem.php?cid=691&pid=1003题意:找出一个字符串满足至少 ...
- BestCoder Round #50 (div.1) 1003 The mook jong (HDU OJ 5366) 规律递推
题目:Click here 题意:bestcoder 上面有中文题目 分析:令f[i]为最后一个木人桩摆放在i位置的方案,令s[i]为f[i]的前缀和.很容易就能想到f[i]=s[i-3]+1,s[i ...
- hdu 5637 BestCoder Round #74 (div.2)
Transform Accepts: 7 Submissions: 49 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072 ...
随机推荐
- servletConfig和ServletContext 以及servletContextListener介绍
<servlet> <servlet-name>BeerParamTests</servlet-name> <servlet-class> ...
- 0x16 Trie
这章刷的真带劲 嘿嘿 裸题 #include<cstdio> #include<iostream> #include<cstring> #include<cs ...
- nyoj--120--校园网络(scc+缩点)
校园网络 时间限制:3000 ms | 内存限制:65535 KB 难度:5 描述 南阳理工学院共有M个系,分别编号1~M,其中各个系之间达成有一定的协议,如果某系有新软件可用时,该系将允许一些其 ...
- 【POJ 2352】 Stars
[题目链接] http://poj.org/problem?id=2352 [算法] 树状数组 注意x坐标为0的情况 [代码] #include <algorithm> #include ...
- DB-MySQL:MySQL 序列使用
ylbtech-DB-MySQL:MySQL 序列使用 1.返回顶部 1. MySQL 序列使用 MySQL 序列是一组整数:1, 2, 3, ...,由于一张数据表只能有一个字段自增主键, 如果你想 ...
- HttpClient连接超时及读取超时
HttpClient连接超时及读取超时 httpClient在执行具体http请求时候 有一个连接的时间和读取内容的时间: HttpClient连接时间 所谓连接的时候 是HttpClient发送请求 ...
- Repeater 中 OnItemCommand 用法
<table> <asp:Repeater ID="rptList" runat="server"OnItemCommand="rp ...
- BZOJ 1989 概率相关
思路: 一条边免费的概率为 (经过它的路/总路径条数)^2 DFS即可 有个地方没有用 long long炸了好久- //By SiriusRen #include <cstdio> us ...
- php开启CURL支持
window下安装php_curl支持 1. 找到php.ini 修改extension=php_curl.dll 把前面的分号去掉2. 把 php_curl.dll libeay32.dll ssl ...
- popupwindows
<1>.能够点击popupwindow 内部空间,外部触摸消失,外部点击事件. package myapplication.com.myapplication; import androi ...