bzoj 4289 TAX —— 点边转化

Posted zinn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 4289 TAX —— 点边转化相关的知识,希望对你有一定的参考价值。

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4289

把边转化成点,同一个原有点相连的边中,边权小的向大的连差值的边,大的向小的连0的边;

一开始想的是给每个新点记一个点权是这个点(边)原来的权,走到它时先加上点权,因为要在原图上经过这条边还是要花费边权;

但是这样在原图中的边之间转移时会把它们的边权都加上,就不对了;

所以应该是把原图的边进一步拆成两个点,两端点的集合各加入一个,这两点之间连原边权的边;

题目上什么也没说...总之 dis 是 long long 的;

如果直接把刚才存边用的结构体放进 queue,就要注意把结构体的 w 定义成 ll,而且一定注意结构体内部定义变量的顺序!因为 (N){..., ...} 的写法是强调顺序的!

——然后发现这道题三个月前做过-_- https://www.cnblogs.com/Zinn/p/9326302.html

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define pb push_back
using namespace std;
typedef long long ll;
int const xn=2e5+5,xm=1e5+5;
int n,m,s,t,hd[xn<<1],ct,to[xn<<3],nxt[xn<<3],w[xn<<3];
ll dis[xn<<1];
bool vis[xn<<1];
struct N{
  ll w; int id;//ll(dis)
  bool operator < (const N &y) const
  {return w<y.w;}
};
vector<N>v[xm];
priority_queue<N>q;
int rd()
{
  int ret=0,f=1; char ch=getchar();
  while(ch<0||ch>9){if(ch==-)f=0; ch=getchar();}
  while(ch>=0&&ch<=9)ret=(ret<<3)+(ret<<1)+ch-0,ch=getchar();
  return f?ret:-ret;
}
void add(int x,int y,int z){to[++ct]=y; nxt[ct]=hd[x]; w[ct]=z; hd[x]=ct;}
void dij()
{
  while(q.size())
    {
      int x=q.top().id; q.pop();
      if(vis[x])continue; vis[x]=1;
      for(int i=hd[x],u;i;i=nxt[i])
    {
      if(dis[u=to[i]]>dis[x]+w[i])
        dis[u]=dis[x]+w[i],q.push((N){-dis[u],u});
    }
    }
}
int main()
{
  n=rd(); m=rd(); s=0; t=2*m+1;
  for(int i=1,x,y,z;i<=m;i++)
    {
      x=rd(); y=rd(); z=rd();
      v[x].pb((N){z,i}); v[y].pb((N){z,i+m});
      add(i,i+m,z); add(i+m,i,z);
    }
  for(int i=0;i<v[1].size();i++)add(s,v[1][i].id,v[1][i].w);
  for(int i=0;i<v[n].size();i++)add(v[n][i].id,t,0);//0
  for(int i=1;i<=n;i++)
    {
      sort(v[i].begin(),v[i].end());
      for(int j=1;j<v[i].size();j++)
    add(v[i][j-1].id,v[i][j].id,v[i][j].w-v[i][j-1].w),add(v[i][j].id,v[i][j-1].id,0);
    }
  memset(dis,0x3f,sizeof dis);
  dis[s]=0; q.push((N){0,s});
  dij(); 
  printf("%lld
",dis[t]);
  return 0;
}

 

以上是关于bzoj 4289 TAX —— 点边转化的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 4289: PA2012 Tax

●BZOJ 4289 PA2012 Tax

bzoj 4289 Tax - 最短路

PA2012BZOJ4289Tax

BZOJ.4289.PA2012 Tax(思路 Dijkstra)

Bzoj4289PA2012 Tax(Dijkstra+技巧建图)