• wenbao与多源多汇最短路


    求多个起点多个终点的最短路,与dij求单源最短路相似,将起点集push进入优先队列,终点集标记,最先遇到的就是最短路

    ------------------------

    http://acm.hdu.edu.cn/showproblem.php?pid=6166

    在一个集合中找出两个点距离最短,

    二进制枚举起点集与终点集,目的是使每个点与其他点不再一个集合当中(巧妙利用二进制位实现)

     1 #include <iostream>
     2 #include <string.h>
     3 #include <queue>
     4 using namespace std;
     5 
     6 #define ll long long 
     7 const int maxn = 100009;
     8 const ll INF = 1e18;
     9 int n, m, q;
    10 int to[maxn], pre[maxn], p[maxn], a[maxn], index;
    11 bool vis[maxn], mark[maxn];
    12 ll dis[maxn], w[maxn];
    13 
    14 struct Node{
    15     int x;
    16     ll y;
    17     bool operator < (const Node &b) const {
    18         return y > b.y;
    19     }
    20 };
    21 
    22 priority_queue<Node> pq;
    23 
    24 void init(){
    25     while(!pq.empty()) pq.pop();
    26     for(int i = 0; i <= n; ++i){
    27         vis[i] = mark[i] = false, dis[i] = INF;
    28     }
    29 }
    30 ll Dij(){
    31     while(!pq.empty()){
    32         Node b = pq.top(); pq.pop();
    33         int xx = b.x;
    34         if(mark[xx]) return b.y;
    35         if(vis[xx]) continue;
    36         vis[xx] = true;
    37         for(int i = p[xx]; i; i = pre[i]){
    38             int xxx = to[i];
    39             if(!vis[xxx] && dis[xxx] > dis[xx] + w[i]){
    40                 dis[xxx] = dis[xx] + w[i];
    41                 pq.push(Node{xxx, dis[xxx]});
    42             }
    43         }
    44     }
    45     return INF;
    46 }
    47 
    48 void solve(){
    49     ll sum = INF;
    50     for(int i = 0; i < 20; ++i){
    51         init();
    52         for(int j = 0; j < q; ++j){
    53             if(a[j] & (1<<i)){
    54                 mark[a[j]] = true;
    55             }else{
    56                 dis[a[j]] = 0;
    57                 pq.push(Node{a[j], 0});
    58             }
    59         }
    60         sum = min(sum, Dij());
    61         init();
    62         for(int j = 0; j < q; ++j){
    63             if(a[j] & (1<<i)){
    64                 dis[a[j]] = 0;
    65                 pq.push(Node{a[j], 0});
    66             }else{
    67                 mark[a[j]] = true;
    68             }
    69         }
    70         sum = min(sum, Dij());
    71     }
    72     printf("%lld
    ", sum);
    73 }
    74 
    75 int main(){
    76     int t, cas = 1;
    77     scanf("%d", &t);
    78     while(t--){
    79         index = 1;
    80         scanf("%d%d", &n, &m);
    81         for(int i = 0; i <= n; ++i) p[i] = 0;
    82         int x, y;
    83         ll z;
    84         for(int i = 0; i < m; ++i){
    85             scanf("%d%d%lld", &x, &y, &z);
    86             to[index] = y, w[index] = z, pre[index] = p[x], p[x] = index ++;
    87         }
    88         scanf("%d", &q);
    89         for(int i = 0; i < q; ++i){
    90             scanf("%d", &a[i]);
    91         }
    92         printf("Case #%d: ", cas++);
    93         solve();
    94     }
    95     return 0;
    96 }

    ------------------------------------

    http://acm.hdu.edu.cn/showproblem.php?pid=2066

    spfa

     1 #include "iostream"
     2 #include <string.h>
     3 #include <queue>
     4 #include <vector>
     5 using namespace std;
     6 
     7 #define ll long long
     8 const int maxn =  1010;
     9 int n, m, s, t, from, to, snum, tnum;
    10 ll T[maxn], val, sum;
    11 bool mark[maxn];
    12 vector<int> a[maxn];
    13 vector<ll> b[maxn];
    14 
    15 void init() {
    16     sum = 1e9;
    17     for(int i = 0; i < maxn; ++i) {
    18         a[i].clear(), b[i].clear();
    19         mark[i] = false;
    20     }
    21 }
    22 
    23 void add(int x, int y, ll z) {
    24     int len = a[x].size();
    25     for(int i = 0; i < len; ++i) {
    26         if(a[x][i] == y) {
    27             if(z < b[x][i]) b[x][i] = z;
    28             return ;
    29         }
    30     }
    31     a[x].push_back(y);
    32     b[x].push_back(z);
    33 }
    34 
    35 void spfa() {
    36     memset(T, 0x3f, sizeof(T));
    37     queue<int> q;
    38     for(int i = 0; i < snum; ++i) {
    39         scanf("%d", &to);
    40         T[to] = 0;
    41         mark[to] = true;
    42         q.push(to);
    43     }
    44     while(!q.empty()) {
    45         int k = q.front();
    46         q.pop();
    47         mark[k] = false;
    48         for(int i = 0; i < a[k].size(); i++) if(T[k] + b[k][i] < T[a[k][i]]) {
    49             T[a[k][i]] = T[k] + b[k][i];
    50             if(!mark[a[k][i]]) {
    51                 q.push(a[k][i]);
    52                 mark[a[k][i]] = true;
    53             }
    54         }
    55     }
    56     for(int i = 0; i < tnum; ++i){
    57         scanf("%d", &to);
    58         if(T[to] < sum) sum = T[to];
    59     }
    60 }
    61 
    62 int main() {
    63 #ifdef wenbao
    64     freopen("in", "r", stdin);
    65 #endif
    66     while(~scanf("%d%d%d", &m, &snum, &tnum)) {
    67         init();
    68         for(int i = 0; i < m; i++) {
    69             scanf("%d%d%lld", &from, &to, &val);
    70             add(from, to, val);
    71             add(to, from, val);
    72         }
    73         s = 0, t = m+1;
    74         spfa();
    75         printf("%lld
    ", sum);
    76     }
    77     return 0;
    78 }

    dij

     1 #include "iostream"
     2 #include <string.h>
     3 #include <queue>
     4 using namespace std;
     5 
     6 #define ll long long
     7 const int maxn = 2020;
     8 const ll INF = 1e18;
     9 int n, snum, tnum;
    10 int to[maxn], pre[maxn], p[maxn], a[maxn], index;
    11 bool vis[maxn], mark[maxn];
    12 ll dis[maxn], w[maxn];
    13 
    14 struct Node {
    15     int x;
    16     ll y;
    17     bool operator < (const Node &b) const {
    18         return y > b.y;
    19     }
    20 };
    21 
    22 priority_queue<Node> pq;
    23 
    24 void init() {
    25     while(!pq.empty()) pq.pop();
    26     for(int i = 0; i < maxn; ++i) {
    27         vis[i] = mark[i] = false, dis[i] = INF;
    28     }
    29 }
    30 ll Dij() {
    31     while(!pq.empty()) {
    32         Node b = pq.top();
    33         pq.pop();
    34         int xx = b.x;
    35         if(mark[xx]) return b.y;
    36         if(vis[xx]) continue;
    37         vis[xx] = true;
    38         for(int i = p[xx]; i; i = pre[i]) {
    39             int xxx = to[i];
    40             if(!vis[xxx] && dis[xxx] > dis[xx] + w[i]) {
    41                 dis[xxx] = dis[xx] + w[i];
    42                 pq.push(Node {xxx, dis[xxx]});
    43             }
    44         }
    45     }
    46     return INF;
    47 }
    48 
    49 void solve() {
    50     init();
    51     int x;
    52     for(int j = 0; j < snum; ++j) {
    53         scanf("%d", &x);
    54         dis[x] = 0;
    55         pq.push(Node {x, 0});
    56     }
    57     for(int i = 0; i < tnum; ++i){
    58         scanf("%d", &x);
    59         mark[x] = true;
    60     }
    61     ll sum = Dij();
    62     printf("%lld
    ", sum);
    63 }
    64 
    65 int main() {
    66 #ifdef wenbao
    67     freopen("in", "r", stdin);
    68 #endif
    69     while(~scanf("%d%d%d", &n, &snum, &tnum)) {
    70         index = 1;
    71         for(int i = 0; i < maxn; ++i) p[i] = 0;
    72         int x, y;
    73         ll z;
    74         for(int i = 0; i < n; ++i) {
    75             scanf("%d%d%lld", &x, &y, &z);
    76             to[index] = y, w[index] = z, pre[index] = p[x], p[x] = index ++;
    77             to[index] = x, w[index] = z, pre[index] = p[y], p[y] = index ++;
    78         }
    79         solve();
    80     }
    81     return 0;
    82 }

     floyd

     1 #include "iostream"
     2 using namespace std;
     3 
     4 #define INF 1e9
     5 const int maxn = 1010;
     6 int a[maxn][maxn], n, snum, tnum, x, y, z, b[maxn], c[maxn], sum, m;
     7 
     8 void init() {
     9     sum = INF, m = 0;
    10     for(int i = 0; i < maxn; ++i) {
    11         for(int j = 0; j < i; ++j) {
    12             a[i][j] = a[j][i] = INF;
    13         }
    14     }
    15 }
    16 
    17 void floyd() {
    18     int tt, s_kj, s_jk, a_ki, xx;
    19     for (int k = 1; k <= m; k++) {
    20         for (int i = 1; i <= m; i++) if (k != i) {
    21             k < i ? a_ki = a[i][k], tt = k : a_ki = a[k][i], tt = i;
    22             // skip if no path
    23             if (a_ki == INF) continue;
    24             for (int j = 1; j < tt; j++) {
    25                 s_kj = a_ki + a[k][j];
    26                 if( s_kj < a[i][j] ) a[i][j] = s_kj;
    27             }
    28             for (int j = k + 1; j < i; j++) {
    29                 s_jk = a_ki + a[j][k];
    30                 if( s_jk < a[i][j] ) a[i][j] = s_jk;
    31             }
    32         }
    33     }
    34 }
    35 
    36 int main() {
    37 #ifdef wenbao
    38     freopen("in", "r", stdin);
    39 #endif
    40     while(~scanf("%d%d%d", &n, &snum, &tnum)) {
    41         init();
    42         for(int i = 0; i < n; ++i) {
    43             scanf("%d%d%d", &x, &y, &z);
    44             if(z < a[x][y]) a[x][y] = a[y][x] = z;
    45             if(x > m) m = x;
    46             if(y > m) m = y;
    47         }
    48         floyd();
    49         for(int i = 0; i < snum; ++i) {
    50             scanf("%d", &b[i]);
    51         }
    52         for(int i = 0; i < tnum; ++i) {
    53             scanf("%d", &c[i]);
    54         }
    55         for(int i = 0; i < snum; ++i) {
    56             for(int j = 0; j < tnum; ++j) {
    57                 if(b[i] > c[j]) {
    58                     if(a[b[i]][c[j]] < sum) sum = a[b[i]][c[j]];
    59                 } else {
    60                     if(a[c[j]][b[i]] < sum) sum = a[c[j]][b[i]];
    61                 }
    62             }
    63         }
    64         printf("%d
    ", sum);
    65     }
    66     return 0;
    67 }

     -----------------------------------------------------------

    -------------------------------------------------------------

    只有不断学习才能进步!

  • 相关阅读:
    RMAN异机还原遭遇ORA-19698错误案例
    Linux sendmail发送邮件失败诊断案例(一)
    Oracle system identifier(SID) "xxx" alread exits. Specify another SID
    ORA-12516:TNS:listener could not find available handler with matching protocol stack
    ORACLE编译失效对象小结
    Win7 安装SQL SERVER 2012需要SP1补丁
    SQL SERVER出现大量一致性错误的解决方法
    MS SQL统计信息浅析下篇
    Dell PowerVault TL4000 磁带机卡带问题
    虚拟机VMWARE上ORACLE License 的计算
  • 原文地址:https://www.cnblogs.com/wenbao/p/7453758.html
Copyright © 2020-2023  润新知