zoukankan      html  css  js  c++  java
  • BZOJ 4289: PA2012 Tax 差分建图 最短路

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

    https://www.cnblogs.com/clrs97/p/5046933.html  claris的题解很清晰

    如果单纯把无向边拆成有向边然后变成点再连有向边需要建m^2条边。

    那么这里可以差分建图压缩新图边的数量,把原图每个点的出边和入边排序,权值相同的出边到入边(开始是无向图所以每个出边一定有权值相同的入边,入边也是)连一条权值为相同权值的边。

    (从小到大排序后)每条出边往它的前一条边连一条权值为0的边,向后一条边连一条权值为 (后一条边权值)-(当前边权值) 的边。

    最后设置一个总入点和总出点相应连1的出边和n的入边就可以了。

    合理性就不再说了。

    空间要注意,这道题空间开小了wa开大了tle。卡了半天......

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<queue>
     7 using namespace std;
     8 #define LL long long
     9 #define pa pair<LL,int>
    10 const int maxn=210000;
    11 int n,m;
    12 struct node{ int x,y;LL v; }a[maxn*2],b[maxn*2];int cnt=0;
    13 struct nod1{ int y,z,next; }e1[maxn*2];
    14 struct nod{ int y,next;LL v;}e[maxn*10];
    15 int head1[maxn]={},head[maxn*2]={},tot1=0,tot=0;
    16 priority_queue< pa ,vector< pa > , greater< pa > >q;
    17 int S,T; LL dis[maxn*2]={};
    18 inline void init1(int x,int y,int z){e1[++tot1].y=y;e1[tot1].z=z;e1[tot1].next=head1[x];head1[x]=tot1;}
    19 inline void init(int x,int y,LL v){e[++tot].y=y;e[tot].v=v;e[tot].next=head[x];head[x]=tot;}
    20 bool mcmp(node aa,node bb){return aa.v<bb.v;}
    21 void Dij(){
    22     memset(dis,63,sizeof(dis));
    23     dis[S]=0;q.push(make_pair(dis[S],S));
    24     while(!q.empty()){
    25         LL v=q.top().first;int x=q.top().second;q.pop();
    26         if(v>dis[x])continue;
    27         for(int i=head[x];i;i=e[i].next){
    28             if(dis[e[i].y]>dis[x]+e[i].v){
    29                 dis[e[i].y]=dis[x]+e[i].v;
    30                 q.push(make_pair(dis[e[i].y],e[i].y));
    31             }
    32         }
    33     }
    34 }
    35 int main(){
    36     scanf("%d%d",&n,&m);
    37     int x,y;LL z;
    38     for(int i=1;i<=m;i++){
    39         scanf("%d%d%lld",&x,&y,&z);
    40         a[++cnt].x=x;a[cnt].y=y;a[cnt].v=z;
    41         a[++cnt].x=y;a[cnt].y=x;a[cnt].v=z;
    42         init1(x,cnt,cnt-1);init1(y,cnt-1,cnt);//入边 出边
    43     }
    44     S=cnt+1;T=S+1;
    45     for(int i=1;i<=n;i++){
    46         int zz=0;
    47         for(int j=head1[i];j;j=e1[j].next){
    48             b[++zz].x=e1[j].y; b[zz].y=e1[j].z; b[zz].v=a[e1[j].y].v;
    49         }
    50         sort(b+1,b+1+zz,mcmp);
    51         for(int j=1;j<=zz;j++)init(b[j].x,b[j].y,b[j].v);
    52         for(int j=1;j<zz;j++){init(b[j+1].y,b[j].y,0); init(b[j].y,b[j+1].y,b[j+1].v-b[j].v);}
    53     }
    54     for(int i=1;i<=cnt;i++){
    55         if(a[i].y==n)init(i,T,a[i].v);
    56         if(a[i].x==1)init(S,i,a[i].v);
    57     }
    58     Dij();
    59     printf("%lld
    ",dis[T]);
    60     return 0;
    61 }
    View Code

  • 相关阅读:
    Java中的静态方法
    捕获异常代码
    重载与重写的区别
    继承代码
    Android Studio 快捷键一览
    android两种基本联网方式与一种第三方开源项目的使用
    Android Studio导入github下载的project和module
    SlidingMenu 侧滑菜单的用法
    显示图片的(自定义)吐司Toast
    用volley在Genymotion上获取网页源码
  • 原文地址:https://www.cnblogs.com/137shoebills/p/8873761.html
Copyright © 2011-2022 走看看