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
原文地址:https://www.cnblogs.com/justPassBy/p/4521479.html