Yali 19 - 8 - 6 test T2 猪国(pig) 题解

T2 猪国

题?描述

猪国是?个由 \(n\) 个城市组成的国家。
国王意识到了“要致富,先修路”这句话的重要性,它决定?规模修路。不巧的是,猪国的
猪们不太会?程,于是只能请隔壁鸡国的鸡建狂魔来帮忙修路。鸡建狂魔看不起猪,于是随
便建设了 \(m\) 条单向的路。尽管如此,每条路还是产?了或多或少的价值。
路修好了,经济却上不来。国王经过调研,发现了道路的巨?缺陷。具体来说,猪?们?向
感不好,?旦存在若?条路能组成?个环,那么可怜的猪?就有可能在环??绕来绕去,这
样甚?会产?反效果。
国王认为这不good。它决定改进这些路使得路再也不能组成环,这样就很good。
国王找到了鸡建狂魔要求售后服务,但鸡建狂魔只答应把若?条路反向,同时还要求收取费
?。国王不??被任意宰割,经过谈判,总费?为被反向的路的价值的最?值。
鸡建狂魔保证有办法使路变得good。国王想知道把路变得good的最?费?。当然,如果这
些路本来就很good,那么说明国王的调研有问题,?然费?就是 0。

输?格式

第??两个整数 \(n, m\)分别表?城市的数?和道路的数?。
接下来 ?,每?三个整数\(x , y , z\)表?这是?条从$ x \(城市单向到\) y \(城市的路,它的价值为\) z $。

输出格式

???个整数表?答案。

样例

Input 1
5 6
2 1 1
5 2 6
2 3 2
3 4 3
4 5 5
1 5 4
Output 1
2

Input 2
5
7
2 1 5
3 2 3
1 3 3
2 4 1
4 3 5
5 4 1
1 5 3
Output 2
3

数据范围
对于 30% 的数据,n,m <= 20 。
对于 60% 的数据,n,m <= 100 。
对于 100% 的数据,2 <= n, m < 1e5,1 <= x, y <= n, 1 <= z <= 1e9。
数据有梯度。

首先,我们看到出题人很(mo)(ming)(qi)(miao)的题解。

?分答案。把所有边权?于当前?分值的边拿出来建?个图。
有环就不?,否则就可以(?边都从拓扑序?点的连向拓扑序?的,?定没有环)。

但事实上,博主的思路是这样的。(事实上是一样的)

二分答案出一个值(data)(注意,这里的data是“被反向的路的价值的最?值”),边权大于这个data的边都不能动(边权小于data的您随意捣鼓)。于是乎就用这些不能动的边造一张图。好嘛,图造好了,拓扑一下,如果叼出来一个环,那显然不符合pig king的要求,那么就得吧data往上升,卡掉环内的一些边。(因为你想让这个图变成一个DAG,你至少得把这个图给摧毁)。哟,升多了,还得降。这样慢慢二分刨刨出来的data,就一定是最合适的data.这样做的话,时间复杂度是O(n log n),没问题

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
const int maxm = 1e5 + 5;
// n , m 的范围。
struct edge{int to, z;};
vector <edge> e[maxn];
// vector 存图
struct group{int u,v,w;}g[maxm];
// 用struct保存每一条边,以便二分时不断建图。
int n, m, x, y, z, cnt, ans;
//ans 是 最终的 data
void init(){
    for(int i = 1;i <= n;i ++){
        e[i].clear();
    }
}
//每次建图之前需要清零
bool work(int limit){
    //拓扑排序
    queue <int> q;
    int rd[maxn] = {0}, dot = 0;
    //dot是拓扑确定顺序的点数的数量
    init();
    for(int i = 1;i <= m;i ++){
        if(g[i].w > limit){
            e[g[i].u].push_back((edge){g[i].v,g[i].w});
            rd[g[i].v] ++;
        }
    }
    //建图
    for(int i = 1;i <= n;i ++){
        if(rd[i] == 0){
            dot ++;
            q.push(i);
        }
    }
    while(!q.empty()){
        int x = q.front();
        q.pop();
        for(int i = 0;i < e[x].size(); i ++){
            int y = e[x][i].to;
            rd[y] --;
            if(rd[y] == 0){
                q.push(y);
                dot ++;
            }
        }
    }
    //标准的topsort过程
    return dot == n;
    //如果图中有环,那么有些点显然是无法确定顺序的,自然dot != n
}
int main(){
    scanf("%d%d", &n, &m);
    for(int i = 1;i <= m;i ++){
        scanf("%d%d%d", &x, &y, &z);
        g[++ cnt] = (group){x,y,z};
        //记录边数
    }
    int l = 0, r = 1e9;
    //二分data
    while(l <= r){
        int mid = l + r >> 1;//当前data
        if(!work(mid)){//如果当前data都爆出了环,那更小的data您就别想了
            l = mid + 1;
        } else {
            //如果可以的话,那就再更苛刻的范围内求data
            r = mid - 1;
            ans = mid;
        }
    }
    cout << ans;
    return 0;
}

原文地址:https://www.cnblogs.com/yangxuejian/p/11318598.html

时间: 2024-10-06 11:51:59

Yali 19 - 8 - 6 test T2 猪国(pig) 题解的相关文章

洛谷P2482 [SDOI2010]猪国杀

题目:https://www.luogu.org/problemnew/show/P2482 题目描述 <猪国杀>是一种多猪牌类回合制游戏,一共有三种角色:主猪,忠猪,反猪.每局游戏主猪有且只有一只,忠猪和反猪可以有多只,每只猪扮演一种角色. 游戏目的: 主猪(MP):自己存活的情况下消灭所有的反猪. 忠猪(ZP):不惜一切保护主猪,胜利条件与主猪相同. 反猪(AP):杀死主猪. 游戏过程: 游戏开始时候,每个玩家手里都会有4张牌,且体力上限和初始体力都是4. 开始游戏时,从主猪开始,按照逆时

洛谷P2482 猪国杀

题目描述 <猪国杀>是一种多猪牌类回合制游戏,一共有三种角色:主猪,忠猪,反猪.每局游戏主猪有且只有一只,忠猪和反猪可以有多只,每只猪扮演一种角色. 游戏目的: 主猪(MP):自己存活的情况下消灭所有的反猪. 忠猪(ZP):不惜一切保护主猪,胜利条件与主猪相同. 反猪(AP):杀死主猪. 游戏过程: 游戏开始时候,每个玩家手里都会有4张牌,且体力上限和初始体力都是4. 开始游戏时,从主猪开始,按照逆时针方向(数据中就是按照编号从1,2,3..n,1..的顺序)依次行动. 每个玩家自己的回合可以

[SDOI2010]猪国杀

一个能看的题面 : https://mubu.com/doc/2707815814591da4 晚上闲的没事干被Refun忽悠着写猪国杀玩 然后一下子写到现在 浪费了一晚上+一上午 这题一堆肥肠SB的规则总之就是让你用他们的智商玩猪国杀 这是一篇没有任何意义的题解 附上10K的代码 然后那个忽悠我的人一直在嘲讽我写的长TAT #include<map> #include<cstdio> #include<vector> #include<cstring> #

Luogu2482 [SDOI2010]猪国杀

题意 ...... https://www.luogu.org/problemnew/show/P2482 总结 题解好像没什么好写的 一些经验吧...... 提前分配好一些比较好的变量名 建议先声明函数再定义函数 打开Dev-C++的代码结构或者自己在草稿纸上写结构 每次调试之前自己浏览一遍代码并手推一遍样例,特别是修改了之后注意自己修改的地方,不要编译了历史版本 不要写的十分复杂,能简单写简单写 善用assert 善用注释 1 //Created By Creeper_LKF 2 //Cau

Luogu P2482 [SDOI2010]猪国杀

Pig Country Kill 很古怪的翻译,不过它确实叫猪(Pig)国(Country)杀(Kill). 我们来好好整理一下这道题目.题面虽较长,但内容基本清晰,只是有部分很Pig的操作部分,很容易让第一次看见这道题目的人百思不得其解. 先整理一下这道长长的题面. First:人物 四位玩家,初始四张手牌,血量上限\(4\),初始血量\(4\),会告诉你整个牌堆的牌,每位玩家每个回合从牌堆顶部抽走两张牌,放在自己手牌的右侧.人物分主猪,忠猪,和反猪,主猪只有一只,反猪和忠猪可以有多只,反猪全

bzoj1972: [Sdoi2010]猪国杀 模拟

模拟.认真读题,理清思路. #include<cstdio> #include<list> #include<cstdlib> const int N=10; #define FOR(a,k)for(A k=P[a].begin();k!=P[a].end();++k) using namespace std; int n,m; int HP[N],ST[N]; bool ID[N],Z[N]; list<char> P[N]; typedef list&l

会飞的猪(Pig)

猪会飞么? 提高pig的性能,让猪飞起来有例如以下办法:1. 尽早地并常常地进行过滤2. 尽早地并常常地进行映射3. 正确并合理地使用Join4. 选择正确的数据类型,合适的并行值5. 调整pig 的性能属性:pig.cachedbag.menusage 和pig.skewedjoin.reduce.memusage6. 对中间结果进行压缩 Describe 命令会显示脚本中指定关系的模式. explain 能够深入到pig内部看怎样将用户的脚本编译成MapReduce任务的. illustra

设计模式之_6大设计原则(转)

一.单一职责原则(Single Responsibility Principle) 定义:不要存在多于一个导致类变更的原因.通俗的说,即一个类只负责一项职责. 问题由来:类T负责两个不同的职责:职责P1,职责P2.当由于职责P1需求发生改变而需要修改类T时,有可能会导致原本运行正常的职责P2功能发生故障. 解决方案:遵循单一职责原则.分别建立两个类T1.T2,使T1完成职责P1功能,T2完成职责P2功能.这样,当修改类T1时,不会使职责P2发生故障风险:同理,当修改T2时,也不会使职责P1发生故

大神刷题表

9月27日 后缀数组:[wikioi3160]最长公共子串 dp:NOIP2001统计单词个数 后缀自动机:[spoj1812]Longest Common Substring II [wikioi3160]最长公共子串 [spoj7258]Lexicographical Substring Search 扫描线+set:[poj2932]Coneology 扫描线+set+树上删边游戏:[FJOI2013]圆形游戏 结论:[bzoj3706][FJ2014集训]反色刷 最小环:[poj1734