zoukankan      html  css  js  c++  java
  • [BZOJ4289][PA2012]Tax

    bzoj

    sol

    把一条边拆成两个点。
    考虑这样一个东西:(max(a,b)=a+max(b-a,0))
    那么我们在每次进入一个点之前把他的入边的权值即(a)加上,在这个点的内部把(max(b-a,0))加上。
    如果(b>a)那么就需要加上额外代价,如果(ble a)额外代价就是零。
    把连接这个点的所有边按权值排序,从下往上相邻连费用为权值差的边,从上往下相邻连0的边。
    新建源点,向所有连1号点的边连费用为权值的边。
    新建汇点,所有连n号点的边向它连费用为0的边。

    code

    #include<cstdio>
    #include<algorithm>
    #include<vector>
    #include<cstring>
    #include<queue>
    #define ll long long
    #define pli pair<ll,int>
    #define mk make_pair
    using namespace std;
    int gi()
    {
    	int x=0,w=1;char ch=getchar();
    	while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    	if (ch=='-') w=0,ch=getchar();
    	while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    	return w?x:-x;
    }
    const int N = 4e5+5;
    int n,m,to[N<<3],nxt[N<<3],head[N],cnt,vis[N];ll ww[N<<3],dis[N];
    vector<pli>S[N];
    priority_queue<pli,vector<pli>,greater<pli> >Q;
    void link(int u,int v,ll w)
    {
    	to[++cnt]=v;nxt[cnt]=head[u];ww[cnt]=w;
    	head[u]=cnt;
    }
    void dijkstra()
    {
    	memset(dis,63,sizeof(dis));
    	dis[2*m+1]=0;Q.push(mk(0,2*m+1));
    	while (!Q.empty())
    	{
    		int u=Q.top().second;Q.pop();
    		if (vis[u]) continue;vis[u]=1;
    		for (int e=head[u];e;e=nxt[e])
    			if (dis[to[e]]>dis[u]+ww[e])
    				dis[to[e]]=dis[u]+ww[e],Q.push(mk(dis[to[e]],to[e]));
    	}
    }
    int main()
    {
    	n=gi();m=gi();
    	for (int i=1;i<=m;++i)
    	{
    		int u=gi(),v=gi();if (u>v) swap(u,v);
    		ll w=gi();
    		S[u].push_back(mk(w,i));
    		S[v].push_back(mk(w,i+m));
    		link(i,i+m,w);link(i+m,i,w);
    		if (u==1) link(2*m+1,i,w);
    		if (v==n) link(i+m,2*m+2,0);
    	}
    	for (int i=1;i<=n;++i)
    	{
    		sort(S[i].begin(),S[i].end());
    		for (int j=1,sz=S[i].size();j<sz;++j)
    		{
    			link(S[i][j-1].second,S[i][j].second,S[i][j].first-S[i][j-1].first);
    			link(S[i][j].second,S[i][j-1].second,0);
    		}
    	}
    	dijkstra();
    	printf("%lld
    ",dis[2*m+2]);return 0;
    }
    
  • 相关阅读:
    查看mysql版本的四种方法及常用命令
    newInstance和new的区别(good)
    Citrix 服务器虚拟化之六 Xenserver虚拟机创建与快照
    Java实现 蓝桥杯 算法训练 排序
    Java实现 蓝桥杯 算法训练 排序
    Java实现 蓝桥杯 算法训练 排序
    Java实现 蓝桥杯 算法训练 2的次幂表示
    Java实现 蓝桥杯 算法训练 2的次幂表示
    Java实现 蓝桥杯 算法训练 前缀表达式
    Java实现 蓝桥杯 算法训练 前缀表达式
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/8663757.html
Copyright © 2011-2022 走看看