codeforces 1100E-Andrew and Taxi
传送门:QAQQAQ
题意:给你一个图,每条边有边权,现在你可以对边进行反转,使图中不存在环,你需要使得反转的边的边权集合中的最大值最小,并输出任意一组解。
思路:二分+拓扑排序
使得最大值最小,自然而然想到二分(其实我先想到tarjan,发现环套环无法处理)
那么我们二分枚举答案,把小于mid的边全部拆了,判断剩下边是否成环(dfs,之前染色方法玄学错误),若没有环则当前mid成立
为什么呢?——如果我们把一条删掉的边连上,无论怎么摆都会形成一个环,那么原先的边一定有一条大环,所以原先这种情况就不可能成立(画个图可以模拟一下)
那么现在我们已经证明删掉的边按照一定顺序摆一定不会有环,我们只需要找出一种这样的顺序。
进行拓扑排序,如果一条边是由拓扑序大的连向拓扑序小的,我们就将它反转,这样就可以保证没有坏
证明:删掉比mid小的边后剩下的一定是若干个DAG,产生环的根本原因是儿子有返祖边,而父亲拓扑序一定比儿子小(因为是用queue维护的),所以若所有边都从拓扑序小的连向拓扑序大的,就一定不会产生返祖边
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=;
struct node{
int from,to,cost,id;
}E[N];
vector<int> v;
int first[N],nxt[N],point[N],w[N],e=,dfn[N];
void add_edge(int x,int y,int z,int num)
{
e++;
E[num].id=e;
point[e]=y; w[e]=z;
nxt[e]=first[x];
first[x]=e;
}
bool cmp(node x,node y)
{
if(x.cost==y.cost) return x.id<y.id;
return x.cost<y.cost;
}
int vis[N],bl[N],n,m,judge,best,in[N];
void dfs(int u)
{
vis[u]=;
for(int i=first[u];i!=-;i=nxt[i])
{
if(bl[i]) continue;
int p=point[i];
if(vis[p]==)
{
judge=;
return;
}
if(!vis[p]) dfs(p);
}
vis[u]=;
return;
}
bool check(int mid)
{
judge=;
memset(vis,,sizeof(vis));
memset(bl,,sizeof(bl));
for(int i=;i<=mid;i++) bl[E[i].id]=;
for(int i=;i<=n;i++)
{
if(!vis[i])
{
dfs(i);
}
}
return judge;
}
int main()
{
memset(first,-,sizeof(first));
memset(nxt,-,sizeof(nxt));
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
scanf("%d%d%d",&E[i].from,&E[i].to,&E[i].cost);
add_edge(E[i].from,E[i].to,E[i].cost,i);
}
sort(E+,E+m+,cmp);
int l=,r=m,mid;best=-;
while(l<=r)
{
mid=(l+r)>>;
if(check(mid)) r=mid-,best=mid;
else l=mid+;
}
queue<int> q;int tot=;
memset(in,,sizeof(in));
for(int i=best+;i<=m;i++)
{
in[E[i].to]++;
}
for(int i=;i<=n;i++) if(!in[i]) q.push(i);
memset(bl,,sizeof(bl));
for(int i=;i<=best;i++) bl[E[i].id]=;
while(!q.empty())
{
int now=q.front();
q.pop();
dfn[now]=++tot;
for(int i=first[now];i!=-;i=nxt[i])
{
if(bl[i]) continue;
int pos=point[i];
in[pos]--;
if(!in[pos]) q.push(pos);
}
}
for(int i=;i<=best;i++)
{
int x=E[i].from;
int y=E[i].to;
if(dfn[x]>dfn[y]) v.push_back(E[i].id);
}
printf("%d %d\n",E[best].cost,(int)v.size());
for(int i=;i<(int)v.size();i++) printf("%d ",v[i]);
return ;
}
codeforces 1100E-Andrew and Taxi的更多相关文章
- CF 1100E Andrew and Taxi(二分答案)
E. Andrew and Taxi time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- CF-1100 E Andrew and Taxi
CF-1100E Andrew and Taxi https://codeforces.com/contest/1100/problem/E 知识点: 二分 判断图中是否有环 题意: 一个有向图,每边 ...
- CF1100E Andrew and Taxi
题目地址:CF1100E Andrew and Taxi 二分,每次取到一个 \(mid\) ,只保留长度 \(>mid\) 的边 dfs判环,若有环,说明 \(ans>mid\) ,否则 ...
- E - E CodeForces - 1100E(拓扑排序 + 二分)
E - E CodeForces - 1100E 一个n个节点的有向图,节点标号从1到n,存在m条单向边.每条单向边有一个权值,代表翻转其方向所需的代价.求使图变成无环图,其中翻转的最大边权值最小的方 ...
- Andrew and Taxi CodeForces - 1100E (思维,拓扑)
大意: 给定有向图, 每条边有一个权值, 假设你有$x$个控制器, 那么可以将所有权值不超过$x$的边翻转, 求最少的控制器数, 使得翻转后图无环 先二分转为判定问题. 每次check删除能动的边, ...
- Codeforces Round #532 (Div. 2) E. Andrew and Taxi(二分+拓扑排序)
题目链接:https://codeforces.com/contest/1100/problem/E 题意:给出 n 个点 m 条边的有向图,要翻转一些边,使得有向图中不存在环,问翻转的边中最大权值最 ...
- E. Andrew and Taxi(二分+拓扑判环)
题目链接:http://codeforces.com/contest/1100/problem/E 题目大意:给你n和m,n代表有n个城市,m代表有m条边,然后m行输入三个数,起点,终点,花费.,每一 ...
- CF1100E Andrew and Taxi 二分答案+拓扑排序
\(\color{#0066ff}{ 题目描述 }\) 给定一个有向图,改变其中某些边的方向,它将成为一个有向无环图. 现在求一个改变边方向的方案,使得所选边边权的最大值最小. \(\color{#0 ...
- Codeforces 1100E 拓扑排序
题意及思路:https://blog.csdn.net/mitsuha_/article/details/86482347 如果一条边(u, v),v的拓扑序小于u, 那么(u, v)会形成环,要反向 ...
- CodeForces - 1100E 二分+拓扑排序
题意: 一个n个节点的有向图,节点标号从1到n,存在m条单向边.每条单向边有一个权值,代表翻转其方向所需的代价.求使图变成无环图,其中翻转的最大边权值最小的方案,以及该方案翻转的最大的边权. Inpu ...
随机推荐
- Codeforces 479【A】div3试个水
题目链接:http://codeforces.com/problemset/problem/977/A 题意:这个题,题目就是让你根据他的规律玩嘛.末尾是0就除10,不是就-1. 题解:题解即题意. ...
- 9.ActiveMQ理论
一.首先说下什么是消息队列? 1.消息队列是在消息的传输过程中保存消息的容器. 二.为什么要用到消息队列? 主要原因是由于在高并发环境下,由于来不及同步处理,请求往往会发生堵塞,比如说,大量的inse ...
- PL SQL 12.0.7的安装及注册码,汉化包,连接Oracle远程数据库,中文乱码问题处理
首先,在官网下载PL SQL 的对应版本,本机是64位的就下载64位的,网址:https://www.allroundautomations.com/downloads.html#PLS 点击应用程序 ...
- 【2-SAT】[JSOI2010]满汉全席
感觉方法和题解差不多,但是题解写的好烦啊...也不是烦,就是很复杂 这里建议开一个数组表示当前这个点选或者不选的编号,这样之后自己理思路也会清楚一点 然而我调了一个小时才发现我是Tarjan写错了.. ...
- windows 10 无法启动 windows update 服务 错误 0x80070005 拒绝访问
windows 10 无法启动 windows update 服务 错误 0x80070005 拒绝访问: 解决方法: 首先重命名系统盘 windows目录下的代号为“SoftwareDistribu ...
- INSTALL_FAILED_TEST_ONLY oppor11p 安装时出现的问题
刚开始出现这个问题 我很懵逼, 因为我之前一直运行都好好的 !!我在网上查了好多资料 试了好几种办法 我先说下我成功的办法 方法1: Android Studio 3.0会在debu ...
- 手写代码注意点 -- HashMap
1.定义 HashMap<String,String> hashMap = new HashMap<>(); <String,String>只需要写一遍 2.获取k ...
- python: 函数递归与尾递归
如果一个函数在内部调用自己,那么这个函数就是递归函数. 例如一个阶乘函数:fact(n)=n! ,其实可以写成 fact(n)=n x fact(n-1). fact(n) 以递归的方式可以表示为: ...
- python使用PIL处理图片后返回给前端的坑
一.python代码 这里有个坑,之前没有将bytes图片数据转成base64就返回到前端了,但在前端处理的时候,怎么都显示不出图片来,虽然数据拿到了,但bytes被传到前后变str了,所以怎么搞都没 ...
- java-day05
数组概念 是一种容器,能够存放多个数据值 特点 多个数据值类型必须统一 是一种引用数据类型 程序运行时,数组长度不可改变 数组初始化 动态初始化格式 数据类型[] 数组名称 = new 数据类型[数组 ...