zoukankan      html  css  js  c++  java
  • Bzoj4289: PA2012 Tax

    题面

    传送门

    Sol

    巧妙的建图+(Dijkstra)
    考虑把边看成点,那么显然暴力建图的边数是(m^2)
    考虑优化
    (max(a, b))变成(a+max(b-a,0))
    把每个点连出的边按权值从小到大排序
    每个边向后面的边连(b-a), 后面向前面连(0)
    连向它的边向连出去的边连(a)
    新建(S)点,向(1)连出的边连,新建(T),连向(n)的边连(T)

    没开long long WA一片

    # include <bits/stdc++.h>
    # define RG register
    # define IL inline
    # define Fill(a, b) memset(a, b, sizeof(a))
    using namespace std;
    typedef long long ll;
    const int _(4e5 + 5);
    typedef int Arr[_];
     
    IL int Input(){
        RG int x = 0, z = 1; RG char c = getchar();
        for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
        for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
        return x * z;
    }
     
    Arr first, vis;
    ll dis[_];
    int n, m, cnt, S, T;
    struct Data{
        int u; ll dis;
     
        IL int operator <(RG Data B) const{
            return dis > B.dis;
        }
    };
    priority_queue <Data> Q;
    struct Edge{
        int to, next, w;
    } edge[_ << 2];
    struct Link{
    	int v, w, id;
    
    	IL int operator <(RG Link B) const{
    		return w < B.w;
    	}
    };
    vector <Link> G[_];
    
    IL void Add(RG int u, RG int v, RG int w){
        edge[cnt] = (Edge){v, first[u], w}, first[u] = cnt++;
    }
     
    IL void Dijkstra(){
        Fill(dis, 63), dis[S] = 0, Q.push((Data){S, 0});
        while(!Q.empty()){
            RG Data x = Q.top(); Q.pop();
            if(vis[x.u]) continue;
            vis[x.u] = 1;
            for(RG int e = first[x.u]; e != -1; e = edge[e].next){
                RG int v = edge[e].to, w = edge[e].w;
                if(dis[x.u] + w < dis[v]) Q.push((Data){v, dis[v] = dis[x.u] + w});
            }
        }
    }
     
    int main(RG int argc, RG char *argv[]){
    	Fill(first, -1), n = Input(), m = Input();
    	for(RG int i = 1; i <= m; ++i){
    		RG int u = Input(), v = Input(), w = Input();
    		G[u].push_back((Link){v, w, i});
    		G[v].push_back((Link){u, w, m + i});
    	}
    	T = m + m + 1; RG int tmp = m;
    	for(RG int i = 1; i <= n; ++i){
    		sort(G[i].begin(), G[i].end()); RG int l = G[i].size();
    		for(RG int j = 0; j < l; ++j){
    			Add((G[i][j].id > tmp ? G[i][j].id - m : G[i][j].id + m), G[i][j].id, G[i][j].w);
    			if(i == 1) Add(S, G[i][j].id, G[i][j].w);
    			if(G[i][j].v == n) Add(G[i][j].id, T, G[i][j].w);
    		}
    		for(RG int j = 0; j < l - 1; ++j){
    			Add(G[i][j].id, G[i][j + 1].id, G[i][j + 1].w - G[i][j].w);
    			Add(G[i][j + 1].id, G[i][j].id, 0);
    		}
    	}
        Dijkstra();
        printf("%lld
    ", dis[T]);
        return 0;
    }
    
    
  • 相关阅读:
    Codeforces 1291 Round #616 (Div. 2) B
    总结
    刷新DNS解析缓存+追踪+域名解析命令
    数学--数论--Hdu 5793 A Boring Question (打表+逆元)
    Lucene.net(4.8.0) 学习问题记录六:Lucene 的索引系统和搜索过程分析
    LeetCode 117 Populating Next Right Pointers in Each Node II
    LeetCode 116 Populating Next Right Pointers in Each Node
    test test
    LeetCode 115 Distinct Subsequences
    LeetCode 114. Flatten Binary Tree to Linked List
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/8663411.html
Copyright © 2011-2022 走看看