• 【UNR #6 A】面基之路(最短路)


    面基之路

    题目链接:UNR #6 A

    题目大意

    给你一个无向图,然后每条边有长度,然后你在 1 号点,有不超过 20 个人在各自的点,每个人每个单位时间能走一个单位长度。
    然后问你最少要多久才能依次跟所有人相遇。(可以在边上)

    思路

    首先发现顺序没问题,就是要这些人会和。
    然后发现自己也不是特殊的,所以问题就是走到一个地方的时间的 max ⁡ \max max min ⁡ \min min

    (直接每个点为起点跑 dij 得到到每个位置的距离)
    然后首先可以枚举每个点,然后考虑边。
    考虑弄一个分界点,如果到左边点的距离小于等于分界点,那就走到左边的点,否则走到右边的点。
    那分界点只要枚举每个点到左边点的距离即可。

    然后好了。

    代码

    #include 
    #include
    #include
    #include
    #define ll long long
    #define INF 0x3f3f3f3f3f3f3f3f
    
    using namespace std;
    
    const int N = 1e5 + 100;
    struct node {
    	int x, to, nxt;
    }e[N << 2];
    int n, m, k, pl[21], X[N << 1], Y[N << 1], Z[N << 1], le[N], KK;
    ll dis[21][N], ans;
    priority_queue <pair<ll, int>, vector<pair<ll, int> >, greater<pair<ll, int> > > q;
    bool in[N];
    
    void add(int x, int y, int z) {e[++KK] = (node){z, y, le[x]}; le[x] = KK;} 
    
    void get_dis(ll *dis, int S) {
    	while (!q.empty()) q.pop(); q.push(make_pair(0, S));
    	dis[S] = 0;
    	memset(in, 0, sizeof(in));
    	while (!q.empty()) {
    		int now = q.top().second; q.pop();
    		if (in[now]) continue; in[now] = 1;
    		for (int i = le[now]; i; i = e[i].nxt)
    			if (dis[e[i].to] > dis[now] + e[i].x) {
    				dis[e[i].to] = dis[now] + e[i].x;
    				q.push(make_pair(dis[e[i].to], e[i].to));
    			}
    	}
    }
    
    int main() {
    //	freopen("ex_trip4.in", "r", stdin);
    	
    	scanf("%d %d", &n, &m);
    	for (int i = 1; i <= m; i++) {
    		int x, y, z; scanf("%d %d %d", &x, &y, &z); z *= 2; X[i] = x; Y[i] = y; Z[i] = z;
    		add(x, y, z); add(y, x, z);
    	}
    	scanf("%d", &k); for (int i = 1; i <= k; i++) scanf("%d", &pl[i]); pl[0] = 1;
    	
    	memset(dis, 0x7f, sizeof(dis));
    	for (int i = 0; i <= k; i++) get_dis(dis[i], pl[i]);
    	
    	ans = INF;
    	for (int i = 1; i <= n; i++) {
    		ll now = 0; for (int j = 0; j <= k; j++) now = max(now, dis[j][i]);
    		ans = min(ans, now);
    	}
    	for (int i = 1; i <= m; i++) {
    		int x = X[i], y = Y[i], z = Z[i];
    		for (int j = 0; j <= k; j++) {
    			ll now1 = 0, now2 = 0;
    			for (int jj = 0; jj <= k; jj++)
    				if (dis[jj][x] <= dis[j][x]) now1 = max(now1, dis[jj][x]);
    					else now2 = max(now2, dis[jj][y]);
    			if (now1 > now2) swap(now1, now2);
    			if (now1 + z <= now2) ans = min(ans, now2);
    				else ans = min(ans, (now1 + now2 + z) / 2);
    		}
    	}
    	printf("%lld", ans);
    	
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
  • 相关阅读:
    25、MySQL 导出数据
    R语言ggplot2可视化条形图:通过双色渐变配色颜色主题可视化条形图、为每个条形添加标签文本(geom_text函数)
    Java22重磅发布!!!!卷不动了,真的卷不动了。。。。
    python初学
    什么是yandex.metrica 目标?
    C. Madoka and Childish Pranks #777 div2
    阿里云oss 批量下载图片(目标文件)阿里云oss
    DevOps-4:Jenkins配置.Net项目模板Job
    【PyCharm Community Edition】:excel操作
    CentOS服务端命令大全
  • 原文地址:https://blog.csdn.net/weixin_43346722/article/details/126236973