CF240E Road Repairs(最小树形图-记录路径)
A country named Berland has n cities. They are numbered with integers from 1 to n. City with index 1 is the capital of the country. Some pairs of cities have monodirectional roads built between them. However, not all of them are in good condition. For each road we know whether it needs repairing or not. If a road needs repairing, then it is forbidden to use it. However, the Berland government can repair the road so that it can be used.
Right now Berland is being threatened by the war with the neighbouring state. So the capital officials decided to send a military squad to each city. The squads can move only along the existing roads, as there's no time or money to build new roads. However, some roads will probably have to be repaired in order to get to some cities.
Of course the country needs much resources to defeat the enemy, so you want to be careful with what you're going to throw the forces on. That's why the Berland government wants to repair the minimum number of roads that is enough for the military troops to get to any city from the capital, driving along good or repaired roads. Your task is to help the Berland government and to find out, which roads need to be repaired.
Input
The first line contains two space-separated integers n and m (1 ≤ n, m ≤ 105) — the number of cities and the number of roads in Berland.
Next m lines contain three space-separated integers ai, bi, ci (1 ≤ ai, bi ≤ n, ai ≠ bi, 0 ≤ ci ≤ 1), describing the road from city ai to city bi. If ci equals 0, than the given road is in a good condition. If ci equals 1, then it needs to be repaired.
It is guaranteed that there is not more than one road between the cities in each direction.
Output
If even after all roads are repaired, it is still impossible to get to some city from the capital, print - 1. Otherwise, on the first line print the minimum number of roads that need to be repaired, and on the second line print the numbers of these roads, separated by single spaces.
The roads are numbered starting from 1 in the order, in which they are given in the input.
If there are multiple sets, consisting of the minimum number of roads to repair to make travelling to any city from the capital possible, print any of them.
If it is possible to reach any city, driving along the roads that already are in a good condition, print 0 in the only output line.
Examples
3 2
1 3 0
3 2 1
1
2
4 4
2 3 0
3 4 0
4 1 0
4 2 1
-1
4 3
1 2 0
1 3 0
1 4 0
0
题解:
题目意思是:给你有向路径,0表示可以走,1表示这条路需要修复才能走,问你要让1号点能走到所有点的最小花费是多少。
思路:最小树形图就是最小代价,输出边的话,就是在zhuliu算法中的缩环的过程中记录需要增加的边和要删除的边,最后倒着处理一遍,剩下的边就是最小树形图上的边。
我们字需要输出边的类型为1的边即可。 参考代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pii pair<int,int>
#define pil pair<int,ll>
#define mkp make_pair
const int INF=0x3f3f3f3f;
const int maxn=1e6+;
struct Edge{
int x,y,w;
int id,real;
} edge[maxn];
int vis[maxn],id[maxn],in[maxn],pre[maxn];
int lastEdge[maxn],used[maxn];
int addEdge[maxn],delEdge[maxn];
int zhuliu(int root,int n,int m)
{
int res=,edgeNum=m;
while(true)
{
for(int i=;i<=n;++i) in[i]=INF;
for(int i=;i<=m;++i)//找到每个点的最小入边及其编号
{
int x=edge[i].x,y=edge[i].y;
if(edge[i].w<in[y] && x!=y)
{
pre[y]=x;
in[y]=edge[i].w;
lastEdge[y]=edge[i].id;
}
}
for(int i=;i<=n;++i)//判断是否可以形成最小树形图
{
if(i==root) continue;
if(in[i]==INF) return -;
}
int cnt=; in[root]=;
memset(id,-,sizeof id);
memset(vis,-,sizeof vis);
for(int i=;i<=n;++i)
{
res+=in[i];
if(i!=root) used[lastEdge[i]]++;
int y=i;
while(vis[y]!=i&&id[y]==-&&y!=root)
{
vis[y]=i;
y=pre[y];
}
if(y!=root && id[y]==-)
{
cnt++;
for(int x=pre[y];x!=y;x=pre[x]) id[x]=cnt;
id[y]=cnt;
}
} if(cnt==) break;
for(int i=;i<=n;++i)//独立点
if(id[i]==-) id[i]=++cnt; for(int i=;i<=m;++i)
{
int x=edge[i].x,y=edge[i].y;
edge[i].x=id[x];edge[i].y=id[y];
if(id[x]!=id[y])
{
edge[i].w-=in[y];
delEdge[++edgeNum]=lastEdge[y];
addEdge[edgeNum]=edge[i].id;
edge[i].id=edgeNum;
}
}
n=cnt;
root=id[root];
} for(int i=edgeNum;i>m;--i)
{
if(used[i])
{
--used[delEdge[i]];
++used[addEdge[i]];
}
}
return res;
} int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
int n,m;
scanf("%d%d",&n,&m);
for(int i=;i<=m;++i)
{
scanf("%d%d%d",&edge[i].x,&edge[i].y,&edge[i].w);
edge[i].id=i;
edge[i].real=edge[i].w;
} int res=zhuliu(,n,m);
if(res==-||res==) printf("%d\n",res);
else
{
printf("%d\n",res);
for(int i=;i<=m;++i)
{
if(used[i]&&edge[i].real)
printf("%d ",i);
}
puts("");
} return ;
}
CF240E Road Repairs(最小树形图-记录路径)的更多相关文章
- Codeforces 240E. Road Repairs 最小树形图+输出路径
最小树形图裸题,只是须要记录路径 E. Road Repairs time limit per test 2 seconds memory limit per test 256 megabytes i ...
- CF240E Road Repairs
最小树形图+输出方案 输出方案的话记录一下哪些边 然后记得最后拆环要倒着拆就行了
- codeforce 240E 最小树形图+路径记录更新
最小树形图的路径是在不断建立新图的过程中更新的,因此需要开一个结构体cancle记录那些被更新的边,保存可能会被取消的边和边在旧图中的id 在朱刘算法最后添加了一个从后往前遍历新建边的循环,这可以理解 ...
- POJ 1015 Jury Compromise (记录路径的背包问题)
(点击此处查看原题) 题意 为了审判某一个人,需要在n个人当中选出m个人组成陪审团,n个人中每个人都有作为起诉方的价值p和作为辩护方的价值d,为了保证公平性,要求m个人作为起诉方的价值之和P和作为辩护 ...
- HDOJ 5294 Tricks Device 最短路(记录路径)+最小割
最短路记录路径,同一时候求出最短的路径上最少要有多少条边, 然后用在最短路上的边又一次构图后求最小割. Tricks Device Time Limit: 2000/1000 MS (Java/Oth ...
- HDU 2121 Ice_cream’s world II 不定根最小树形图
题目链接: 题目 Ice_cream's world II Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Ja ...
- HDU 2121 Ice_cream’s world II 最小树形图 模板
开始学习最小树形图,模板题. Ice_cream’s world II Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32 ...
- [JSOI2008]小店购物 & bzoj4349:最小树形图 最小树形图
---题面(洛谷)--- ---题面(bzoj)--- 其实是同一道题,,,样例都一模一样 题解: 一开始看想了好久,,,还想到了最短路和最小生成树,,然而写的时候才意识到最小生成树应该要用无向边 其 ...
- kuangbin带你飞 生成树专题 : 次小生成树; 最小树形图;生成树计数
第一个部分 前4题 次小生成树 算法:首先如果生成了最小生成树,那么这些树上的所有的边都进行标记.标记为树边. 接下来进行枚举,枚举任意一条不在MST上的边,如果加入这条边,那么肯定会在这棵树上形成一 ...
随机推荐
- 数据仓库ETL案例学习(一)
来自课程案例学习 某跨国食品超市的信息管理系统,每天都会记录成千上万条各地连锁超市的销售数据.基于大数据的背景,该公司的管理层决定建立FoodMart数据仓库,期望能从庞大的数据中挖掘出有商业价值 ...
- 将 /u 转变为 utf-8 编码
将 /u 转变为 utf-8 编码 PHP实例: $result = {"errno":-1,"message":"\u8bbf\u95ee\u5fa ...
- ASP.NET购物车Cookie获取,创建,添加,更新,删除的用法
#region 添加购物车 public void GetShoppingCart(int skuId, int quanlity) { HttpCookie cookie = HttpContext ...
- 022.掌握Pod-Pod升级和回滚
一 deploymentPod升级和回滚 1.1 deployment升级 若Pod是通过Deployment创建的,可以在运行时修改Deployment的Pod定义(spec.template)或镜 ...
- 函数的prototype
1.函数的prototype属性 每一个函数都有一个prototype属性,默认指向object空对象(原型对象),每一个原型对象都有一个constructor属性,指向函数对象 2.给原型对象添加属 ...
- 领扣(LeetCode)字符串相加 个人题解
给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和. 注意: num1 和num2 的长度都小于 5100. num1 和num2 都只包含数字 0-9. num1 和num2 都不包 ...
- LeetCode 5272. 5272. 统计参与通信的服务器 Count Servers that Communicate
地址 https://leetcode-cn.com/problems/count-servers-that-communicate/ 题目描述这里有一幅服务器分布图,服务器的位置标识在 m * n ...
- jsp页面使用EL表达式 使用Jstl标签库中的标签,需要引入jstl.jar和standard.jar
spring boot 中使用jstl 首先在pom中加入 <dependency> <groupId>jstl</groupId> <artifactId& ...
- UML组件图
组件图用于可视化在一个系统中的物理组件.这些组件包括库,程序包,文件等. 组件图 = 构件(Component)+接口(Interface)+关系(Relationship)+端口(Port)+连接器 ...
- Intellij IDEA如何设置快速调整字体大小的快捷键
Intellij IDEA快速调整字体大小的快捷键 第一种方法(方便) 单击左上角File,找到Settings并点击.(当然也可以直接Alt+Ctrl+s) 点击Editor下的General,勾选 ...