zoukankan      html  css  js  c++  java
  • [JZOJ 5818] 做运动

    题意:带温度最短路。
    思路:
    我们将温度从小到大的将边加入,用并查集维护连通性。
    如果一旦联通那么跑一遍\(spfa\)就可以得到答案。
    复杂度\(O(m log m)\)

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int maxn = 1e6 + 10;
    inline int read () {
    	int q=0,f=1;char ch = getchar();
    	while(!isdigit(ch)) {
    		if(ch=='-')f=-1;ch=getchar();
    	}
    	while(isdigit(ch)){
    		q=q*10+ch-'0';ch=getchar();
    	}
    	return q*f;
    }
    int n,m,S,T;
    bool vis[maxn];
    ll dis[maxn];
    int f[maxn];
    int ans;
    int siz[maxn];
    struct edge {
    	int u;
    	int v;
    	int w;
    	int t;
    }e[maxn << 1];
    queue<int>q;
    inline bool cmp(edge x,edge y) {
    	return x.w < y.w;
    }
    int get(edge p,int k) {
    	if(k == p.u) return p.v;
    	return p.u;
    }
    inline int find (int x) {
    	return x == f[x] ? x : f[x] = find(f[x]);
    }
    vector<edge>v[maxn];
    inline void spfa(int s) {
    	memset(dis,-1,sizeof(dis));
    	memset(vis,false,sizeof(vis));
    	dis[s] = 0;
    	vis[s] = 1;
    	q.push(s);
    	while(!q.empty()) {
    		int u = q.front();
    		q.pop();
    		vis[u] = 0;
    		for(int i = 0;i < v[u].size(); ++i) {
    			int y = get(v[u][i],u);
    			if(v[u][i].w > ans) continue;
    			if(dis[y] == -1 || dis[y] > dis[u] + (ll)v[u][i].w * v[u][i].t) {
    				dis[y] = dis[u] + (ll)v[u][i].w * v[u][i].t;
    				if(!vis[y]) {
    					q.push(y);
    					vis[y] = 1;
    				}
    			}
    		}
    	}
    }
    #define pb(x) push_back(x)
    int main () {
    	freopen("running.in","r",stdin);
    	freopen("running.out","w",stdout);
    	n = read(),m = read();
    	for(int i = 1;i <= n; ++i) {
    		f[i] = i;
    		siz[i] = 1;
    	}
    	for(int i = 1;i <= m; ++i) {
    		e[i].u = read(),e[i].v = read(),e[i].w = read(),e[i].t = read();
    		v[e[i].u].pb(e[i]);
    		v[e[i].v].pb(e[i]);
    	}
    	S = read(),T = read();
    	sort(e + 1,e + m + 1,cmp);
    	for(int i = 1;i <= m; ++i) {
    		int x = e[i].u;
    		int y = e[i].v;
    		int l = find(x);
    		int r = find(y);
    		if(l != r) f[l] = r;
    		if(find(S) == find(T)) {
    			ans = e[i].w;
    			break;
    		}
    	}
    	spfa(S);
    	printf("%d %lld",ans,dis[T]);
    	return 0;
    }
    
  • 相关阅读:
    greenplum表的distributed key值查看
    oracle dump的使用心得
    Linux du与df命令的差异
    从语言只是工具说起
    DDD领域模型
    同一个对象在另一个对象中容易出现重复引用造成map覆盖,HiJson出现严重漏洞自动删除了$ref和空值
    乒乓球相关
    字符串转xml
    最新版java题
    list集合进行分页
  • 原文地址:https://www.cnblogs.com/akoasm/p/9596645.html
Copyright © 2011-2022 走看看