• UVA1416/LA4080 Warfare And Logistics


    题目大意:有N个点,M条路,如果两条路不连通的话,就将这两条路的距离设置为L
    现在要求你求出每两点之间的最短距离和
    接着要求
    求出炸断 给出的M条路中的一条路后,每两点之间的最短距离和的最大值(翻译来自http://blog.csdn.net/l123012013048/article/details/47297393)

    单源最短路树:把源点到其他点的最短路拼起来,形成最短路树(可能有多棵,这里只需要一棵)。我们把起点为i的单源最短路树称为i源最短路树。想要让最短路改变,删除的边必定在这课最短路树上(但反过来不成立,即删除最短路树上的边最短路改变,是错误的)。处理出单源最短路树,然后用belong[i][j]表示边i是否在j源最短路树上,枚举边,重新做belong[i][j]为1的点即可。

    这里仅仅是带来常数上的优化,实际复杂度并不能改变(nm^2logn),蓝书说复杂度变了(n^2mlogn)。。我不敢苟同

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cstdlib>
      5 #include <algorithm>
      6 #include <queue>
      7 #include <vector>
      8 #include <map>
      9 #include <string> 
     10 #include <cmath> 
     11 #define min(a, b) ((a) < (b) ? (a) : (b))
     12 #define max(a, b) ((a) > (b) ? (a) : (b))
     13 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a))
     14 template<class T>
     15 inline void swap(T &a, T &b)
     16 {
     17     T tmp = a;a = b;b = tmp;
     18 }
     19 inline void read(int &x)
     20 {
     21     x = 0;char ch = getchar(), c = ch;
     22     while(ch < '0' || ch > '9') c = ch, ch = getchar();
     23     while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
     24     if(c == '-') x = -x;
     25 }
     26 const int INF = 0x3f3f3f3f;
     27 const int MAXN = 200 + 10;
     28 const int MAXM = 2000 + 10;
     29 struct Edge
     30 {
     31     int u,v,w,nxt;
     32     Edge(int _u, int _v, int _w, int _nxt){u = _u, v = _v, w = _w, nxt = _nxt;}
     33     Edge(){}
     34 }edge[MAXM << 1];
     35 int head[MAXN], cnt = 1, d[MAXN][MAXN], dis[MAXM], flag, belong[MAXM][MAXN], vis[MAXN], p[MAXN][MAXN], l, tmp1, tmp2, tmp3, n, m;
     36 //p[i]表示以i为起点的最短路树,在最短路树上,j的父亲的那条边
     37 inline void insert(int a, int b, int c)
     38 {
     39     edge[++ cnt] = Edge(a,b,c,head[a]), head[a] = cnt;
     40 }
     41 struct Node
     42 {
     43     int u,w;
     44     Node(int _u, int _w){u = _u, w = _w;}
     45     Node(){} 
     46 };
     47 struct cmp
     48 {
     49     bool operator()(Node a, Node b)
     50     {
     51         return a.w > b.w;
     52     }
     53 };
     54 std::priority_queue<Node, std::vector<Node>, cmp> q;
     55 void dij(int S, int *d, int size)
     56 {
     57     while(q.size())q.pop();memset(d, 0x3f, size), d[S] = 0, memset(vis, 0, sizeof(vis)), q.push(Node(S, 0));
     58     while(q.size())
     59     {
     60         Node now = q.top();q.pop();
     61         if(vis[now.u]) continue; vis[now.u] = 1;
     62         for(int pos = head[now.u];pos;pos = edge[pos].nxt)
     63         {
     64             int v = edge[pos].v;
     65             if(d[v] > d[now.u] + edge[pos].w) 
     66             {
     67                 d[v] = d[now.u] + edge[pos].w, q.push(Node(v, d[v]));
     68                 if(flag) p[S][v] = pos;
     69             }
     70         }
     71     }
     72 }
     73 int main()
     74 {
     75     while(scanf("%d %d %d", &n, &m, &l) != EOF)
     76     {
     77         flag = 1, memset(head, 0, sizeof(head)), memset(belong, 0, sizeof(belong)), memset(p, 0, sizeof(p)), cnt = 1;
     78         for(int i = 1;i <= m;++ i) read(tmp1), read(tmp2), read(tmp3), insert(tmp1, tmp2, tmp3), insert(tmp2, tmp1, tmp3);
     79         for(int i = 1;i <= n;++ i) dij(i, d[i], sizeof(d[i]));
     80         long long ans1 = 0, ans2 = ans1, ans3 = 0;
     81         for(int i = 1;i <= n;++ i)
     82             for(int j = 1;j <= n;++ j)
     83                 if(d[i][j] >= INF) ans1 += l;
     84                 else ans1 += d[i][j];
     85         printf("%lld ", ans1);
     86         flag = ans3 = 0;
     87         for(int i = 1;i <= n;++ i)
     88             for(int j = 1;j <= n;++ j)
     89                 if(p[i][j]) belong[p[i][j]][i] = 1;
     90         for(int pos = 2;pos <= cnt;pos += 2)
     91         {
     92             tmp1 = edge[pos].w;ans2 = ans1;
     93             edge[pos].w = edge[pos ^ 1].w = INF;
     94             for(int S = 1;S <= n;++ S) 
     95                 if(belong[pos][S] || belong[pos^1][S])
     96                 {
     97                     dij(S, dis, sizeof(dis));
     98                     for(int i = 1;i <= n;++ i)
     99                     {
    100                         if(d[S][i] >= INF) ans2 -= l;
    101                         else ans2 -= d[S][i];
    102                         if(dis[i] >= INF) ans2 += l;
    103                         else ans2 += dis[i]; 
    104                     }
    105                 }
    106             edge[pos].w = edge[pos ^ 1].w = tmp1;
    107             ans3 = max(ans3, ans2);
    108         }
    109         printf("%lld
    ", ans3);
    110     }
    111     return 0;
    112 }
    UVA1416/LA4080
  • 相关阅读:
    Seasar2:SAStruts:View(JSP)
    Seaser2:SAStruts:エラーメッセージの設定
    Seaser2:SAStruts:アクションとアクションフォーム(Struts)
    SAStruts アクションにJSONを返すメソッドを作成してみる
    S2JDBC テーブルを利用した独自仕様のid採番メソッド
    【C++ 异常】error: jump to case label [fpermissive]
    MusicXML 3.0 (15) 倚音
    MusicXML 3.0 (9) 小节线、反复线、终止线
    MusicXML 3.0 (13) 歌词
    MusicXML 3.0 (10) 换行、换页
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/8397479.html
Copyright © 2020-2023  润新知