zoukankan      html  css  js  c++  java
  • 解题:POI 2007 Tourist Attractions

    题面

    事实上这份代码在洛谷过不去,因为好像要用到一些压缩空间的技巧,我并不想(hui)写(捂脸)

    先预处理$1$到$k+1$这些点之间相互的最短路和它们到终点的最短路,并记录下每个点能够转移到时的状态,然后就是状压dp辣。

    设$dp[s][i]$表示状态为$s$时处在点$i$的最短路,就可以$O(2^kk^2)$转移了,注意最好减一些不合法状态,因为这时间挺危险的=。=

     1 #include<queue>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 const int N=20005,M=200005,K=22,inf=0x3f3f3f3f;
     7 struct a{int node,dist;};
     8 bool operator < (a x,a y)
     9 {
    10     return x.dist>y.dist;
    11 }
    12 priority_queue<a> hp;
    13 int dis[N],vis[N],ss[K],dp[(1<<20)+1][K];
    14 int p[N],noww[2*M],goal[2*M],val[2*M],mat[K][K];
    15 int n,m,k,c,t1,t2,t3,cnt,len,all,ans=inf;
    16 void link(int f,int t,int v)
    17 {
    18     noww[++cnt]=p[f],p[f]=cnt;
    19     goal[cnt]=t,val[cnt]=v;
    20 }
    21 void Dijkstra(int s)
    22 {
    23     memset(vis,0,sizeof vis); 
    24     memset(dis,0x3f,sizeof dis);
    25     dis[s]=0,hp.push((a){s,0});
    26     while(!hp.empty())
    27     {
    28         a tt=hp.top(); hp.pop(); int tn=tt.node;
    29         if(vis[tn]) continue ; vis[tn]=true;
    30         for(int i=p[tn];i;i=noww[i])
    31             if(dis[goal[i]]>dis[tn]+val[i])
    32                 dis[goal[i]]=dis[tn]+val[i],hp.push((a){goal[i],dis[goal[i]]});
    33     }
    34 }
    35 int ins(int x)
    36 {
    37     return 1<<(x-2);
    38 }
    39 int main ()
    40 {
    41     scanf("%d%d%d",&n,&m,&k),all=(1<<k)-1;
    42     for(int i=1;i<=m;i++)
    43     {
    44         scanf("%d%d%d",&t1,&t2,&t3);
    45         link(t1,t2,t3),link(t2,t1,t3);
    46     }
    47     scanf("%d",&c);
    48     for(int i=1;i<=c;i++)
    49         scanf("%d%d",&t1,&t2),ss[t2]|=ins(t1);
    50     for(int i=1;i<=k+1;i++)
    51     {
    52         Dijkstra(i);
    53         for(int j=1;j<=k+1;j++)
    54             mat[i][j]=dis[j]; mat[i][0]=dis[n];
    55     }
    56     memset(dp,0x3f,sizeof dp),dp[0][1]=0;
    57     for(int i=0;i<=all;i++)
    58         for(int j=1;j<=k+1;j++)
    59             if(dp[i][j]!=inf)
    60                 for(int h=2;h<=k+1;h++)
    61                     if((i&ss[h])==ss[h])
    62                         dp[i|ins(h)][h]=min(dp[i|ins(h)][h],dp[i][j]+mat[j][h]);
    63     for(int i=1;i<=k+1;i++) ans=min(ans,dp[all][i]+mat[i][0]);
    64     printf("%d",ans);
    65     return 0;
    66 }
    View Code
  • 相关阅读:
    Flowable学习笔记(二、BPMN 2.0-基础 )
    Flowable学习笔记(一、入门)
    只有程序员才懂的幽默
    Navicat自动备份数据库
    两个原因导致Spring @Autowired注入的组件为空
    设计模式—— 十二 :代理模式
    设计模式—— 十 一:建造者模式
    SpringBoot学习笔记(十一:使用MongoDB存储文件 )
    Swagger API文档集中化注册管理
    Spring Boot2从入门到实战:集成AOPLog来记录接口访问日志
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/9808848.html
Copyright © 2011-2022 走看看