• CSU 2005 Nearest Maintenance Point(最短路+bitset)


    https://vjudge.net/problem/CSU-2005

    题意:
    给出带权值的图,图上有一些特殊点,现在给出q个询问,对于每个询问,输出离该点最近的特殊点,如果有多个,则按升序输出。

    思路:
    因为有多次查询,不可能对于每个询问都去跑一遍最短路。必须以特殊点为起点跑一遍最短路,但是这样路径的记录就是问题了。正解是用bitset来记录状态,在最短路松弛更新状态时,继承前驱节点即可。

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cstdio>
      4 #include<cstring>
      5 #include<queue>
      6 #include<bitset>
      7 #include<set>
      8 using namespace std;
      9 const int INF = 0x3f3f3f3f;
     10 const int maxn = 10000+5;
     11 
     12 int n,m,s,q,tot;
     13 int head[maxn],d[maxn],a[1005];
     14 bool done[maxn],flag[maxn];
     15 bitset<1005> ans[maxn];
     16 int tmp[1005];
     17 
     18 struct node
     19 {
     20     int v,w,next;
     21 }e[10*maxn];
     22 
     23 void addEdge(int u, int v, int w)
     24 {
     25     e[tot].v = v;
     26     e[tot].w = w;
     27     e[tot].next = head[u];
     28     head[u] = tot++;
     29 }
     30 
     31 struct HeapNode
     32 {
     33     int u,d;
     34     HeapNode(int u, int d):u(u),d(d){}
     35     bool operator< (const HeapNode& rhs) const
     36     {
     37         return d > rhs.d;
     38     }
     39 };
     40 
     41 
     42 void dijkstra(int st)
     43 {
     44     priority_queue<HeapNode> Q;
     45     for(int i=0;i<=n;i++)  d[i] = INF;
     46     d[st] = 0;
     47     memset(done,0,sizeof(done));
     48     Q.push(HeapNode(st,0));
     49     while(!Q.empty())
     50     {
     51         HeapNode x = Q.top(); Q.pop();
     52         int u = x.u;
     53         if(done[u])  continue;
     54         done[u] = true;
     55         for(int i=head[u];i!=-1;i=e[i].next)
     56         {
     57             int v = e[i].v;
     58             if(d[v] > d[u]+e[i].w)
     59             {
     60                 d[v] = d[u] + e[i].w;
     61                 if(!flag[v]) ans[v] = ans[u]; //如果不是特殊点,就更新
     62                 Q.push(HeapNode(v,d[v]));
     63             }
     64             else if(d[v] == d[u]+e[i].w)  ans[v]|=ans[u];  //相等的话,就加上当前点的答案
     65         }
     66     }
     67 }
     68 
     69 int main()
     70 {
     71     //freopen("in.txt","r",stdin);
     72     while(~scanf("%d%d%d%d",&n,&m,&s,&q))
     73     {
     74         tot = 0;
     75         memset(head,-1,sizeof(head));
     76         memset(flag,0,sizeof(flag));
     77         for(int i=0;i<=n;i++)  ans[i].reset();
     78         for(int i=1;i<=m;i++)
     79         {
     80             int u,v,w;
     81             scanf("%d%d%d",&u,&v,&w);
     82             addEdge(u,v,w);
     83             addEdge(v,u,w);
     84         }
     85         for(int i=1;i<=s;i++)
     86         {
     87             scanf("%d",&a[i]);
     88             addEdge(0,a[i],0);
     89             flag[a[i]] = true;
     90             ans[a[i]].set(i);  //特殊点的答案就是自己
     91         }
     92         dijkstra(0);
     93         while(q--)
     94         {
     95             int tot = 0;
     96             int x;scanf("%d",&x);
     97             for(int i=1;i<=s;i++)
     98                 if(ans[x].test(i))  tmp[tot++]=a[i];
     99             sort(tmp,tmp+tot);
    100             for(int i=0;i<tot;i++)
    101                 printf("%d%c",tmp[i],i==tot-1?'
    ':' ');
    102         }
    103     }
    104     return 0;
    105 }
  • 相关阅读:
    为什么要有binary-to-text encoding?
    海量网络存储系统原理与设计(三)
    Java中的Inner Class (一)
    海量网络存储系统原理与设计(二)
    海量网络存储系统原理与设计(一)
    [JavaScript]顺序的异步执行
    [PAT]素因子分解(20)
    [PAT]求集合数据的均方差(15)
    [PAT]数列求和(20)
    【C-001】printf理解
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7875621.html
Copyright © 2020-2023  润新知