• 洛谷P2176 [USACO11DEC]RoadBlock S / [USACO14FEB]Roadblock G/S


    洛谷P2176 [USACO11DEC]RoadBlock S / [USACO14FEB]Roadblock G/S

    [传送门][https://www.luogu.com.cn/problem/P2176]

    题目描述

    每天早晨,FJ从家中穿过农场走到牛棚。农场由 N 块农田组成,农田通过 M 条双向道路连接,每条路有一定长度。FJ 的房子在 1 号田,牛棚在 N 号田。没有两块田被多条道路连接,以适当的路径顺序总是能在农场任意一对田间行走。当FJ从一块田走到另一块时,总是以总路长最短的道路顺序来走。

    FJ 的牛呢,总是不安好心,决定干扰他每天早晨的计划。它们在 M 条路的某一条上安放一叠稻草堆,使这条路的长度加倍。牛希望选择一条路干扰使得FJ 从家到牛棚的路长增加最多。它们请你设计并告诉它们最大增量是多少。

    输入格式

    第 1 行:两个整数 N, M。

    第 2 到 M+1 行:第 i+1 行包含三个整数 A_i, B_i, L_i,A_i 和 B_i 表示道路 i 连接的田的编号,L_i 表示路长。

    输出格式

    第 1 行:一个整数,表示通过使某条路加倍而得到的最大增量。

    输入输出样例

    输入 #1复制

    5 7
    2 1 5
    1 3 1
    3 2 8
    3 5 7
    3 4 3
    2 4 7
    4 5 2
    

    输出 #1复制

    2
    

    题解

    数据很水, (我一开始居然写了个分层图, 如此智障不愧是我)

    枚举要乘二的边, 每次跑一遍最长路, 其实毫无技术含量

    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    using namespace std;
    const int maxn = 255, maxe = 250005;
    int len, head[maxn], n, m, dis[maxn], vis[maxn];
    struct edge{
    	int next, to, t;
    }e[maxn*maxe];
    void insert(int x, int y, int t){
    	e[++len].to = y;
    	e[len].t = t;
     	e[len].next = head[x];
    	head[x] = len;
    }
    void spfa(int s){
    	memset(dis, 0x3f, sizeof(dis));
    	memset(vis, 0, sizeof(vis));
    	queue<int> que;
    	que.push(s);
    	vis[s] = 1;
    	dis[s] = 0;
    	while(!que.empty()){
    		int u = que.front();
    		que.pop();
    		vis[u] = 0;
    		for(int i=head[u]; i; i=e[i].next){
    			int v = e[i].to;
    			if(dis[v] > dis[u] + e[i].t){
    				dis[v] = dis[u] + e[i].t;
    				if(!vis[v]){
    					que.push(v);
    					vis[v] = 1;
    				}
    			}
    		}
    	}
    }
    int main(){
        scanf("%d%d", &n, &m);
    	for(int i=1; i<=m; i++){
    		int a, b, t;scanf("%d%d%d", &a, &b, &t);
    		insert(a, b, t); insert(b, a, t);
    	}
    	spfa(1); 
    	int time1 = dis[n];
    	int time2 = 0;
    	for(int i=1; i<=2*m; i+=2){
    		e[i].t*=2; e[i+1].t*=2;
    		spfa(1);
    		if(dis[n] > time2) time2 = dis[n];
    		e[i].t/=2; e[i+1].t/=2; 
    	}
    	printf("%d
    ", time2 - time1);
        return 0;
    }
    
  • 相关阅读:
    关于如何实现接口IComparer以实现自己需要的排序规则
    随机移动
    关于资源版本管理的问题
    Unity3D内部脚本编程入门
    删除GameObject上除了Quality子物体之外其他子物体的组件(但不删除transform)
    资料
    c# 基础知识点
    c# 匿名方法(委托)
    git
    一篇关于Unity3D优化的文章,翻译脚本优化部分
  • 原文地址:https://www.cnblogs.com/hzoi-poozhai/p/12838513.html
Copyright © 2020-2023  润新知