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\n",dist[t]);

84     }

85     return 0;

86 }
View Code

 

你可能感兴趣的:(B)