zoukankan      html  css  js  c++  java
  • bnu1066

    hnu1066

    给我们一张图,问我们摧毁边使得s和t不连通有多少种方案, 方案与方案之间不能存在相同的摧毁目标。

    这是一个神奇的题目。

    这题可以转为求s与t的最短路,为什么呢?

    因为方案与方案之间不能存在相同的催婚目标。

    那么最短路上的边肯定要被摧毁,才能使得s和t不连通。

    那么只要一个方案摧毁最短路上的一条边,外加一些最短路外的边, 那么就会使得方案数最多。方案数为最短路的长度。

    那么问题来了,我们摧毁的最短路上的边是不会相同的,但是最短路外的边呢?会不会相同呢?

    我们假设最短路是s -- x1 -- x2 -- x3 -- x4--...---t

    我们删除最短路的第一条边 s--x1,   删除后图可能还是连通的,因为s与x2,x3,x4...t可能还有间接的边。

    s与x2的间接边长度长度至少为2,s与x2的间接边长度至少为3,依次类推。不然原来的最短路就不是最短路了

    所以我们只要删除这些间接边的第一条边。

    我们删除最短路的第二条边 x1--x2, 然后删除以x1开头,删除以s开头的连向x3,x4...t的间接边的第二条边

    删除以x1开头的连向以x1开头,连向x3,x4,...t的间接边的第一条边, 

    以此类推。 摧毁最短路之外的边是不会相同的。

    所以,我们求个s->t的最短路就行了

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <stdlib.h>
     4 #include <algorithm>
     5 #include <iostream>
     6 #include <queue>
     7 #include <stack>
     8 #include <vector>
     9 #include <map>
    10 #include <set>
    11 #include <string>
    12 #include <math.h>
    13 using namespace std;
    14 #pragma warning(disable:4996)
    15 typedef long long LL;                   
    16 const int INF = 1<<30;
    17 /*
    18 
    19 */
    20 struct Edge
    21 {
    22     int to,dist;
    23     bool operator<(const Edge&rhs)const
    24     {
    25         return dist > rhs.dist;
    26     }
    27 };
    28 vector<Edge> g[10000+10];
    29 int dist[10000+10];
    30 bool vis[10000+10];
    31 void dij(int s)
    32 {
    33     priority_queue<Edge> q;
    34     Edge cur,tmp;
    35     cur.dist = 0;
    36     cur.to = s;
    37     q.push(cur);
    38     dist[s] = 0;
    39     while(!q.empty())
    40     {
    41         cur = q.top(); q.pop();
    42         int u = cur.to;
    43         if(vis[u]) continue;
    44         vis[u] = true;
    45         for(int i=0; i<g[u].size(); ++i)
    46         {
    47             int v = g[u][i].to;
    48             if(dist[v] > dist[u] + g[u][i].dist)
    49             {
    50                 tmp.dist = dist[v] = dist[u] + g[u][i].dist;
    51                 tmp.to = v;
    52                 q.push(tmp);
    53             }
    54         }
    55     }
    56 
    57 }
    58 int main()
    59 {
    60     int n,m,s,t,i,a,b;
    61     Edge tmp;
    62     while(true)
    63     {
    64         scanf("%d%d%d%d",&n,&m,&s,&t);
    65         if(n==0)
    66             break;
    67         for(i=1; i<=n; ++i)
    68         {
    69             g[i].clear();
    70             vis[i] = false;
    71             dist[i] = INF;
    72         }    
    73         for(i=0; i<m; ++i)
    74         {
    75             scanf("%d%d",&a,&b);
    76             tmp.to = b;
    77             tmp.dist = 1;
    78             g[a].push_back(tmp);
    79             tmp.to = a;
    80             g[b].push_back(tmp);
    81         }
    82         dij(s);
    83         printf("%d
    ",dist[t]);
    84     }
    85     return 0;
    86 }
    View Code
  • 相关阅读:
    Java虚拟机--编译那点事儿
    Java虚拟机--常用Java命令(二)
    Java虚拟机--常用Java命令(一)
    Java虚拟机--类加载机制
    Java虚拟机--JIT编译器
    Java虚拟机--垃圾回收机制
    Java虚拟机--对象模型
    Junit测试--多个测试接口如何产生业务联系
    Java虚拟机--内存模型
    Java虚拟机--内存结构
  • 原文地址:https://www.cnblogs.com/justPassBy/p/4521479.html
Copyright © 2011-2022 走看看