codeforces 544 D Destroying Roads 【最短路】

题意:给出n个点,m条边权为1的无向边,破坏最多的道路,使得从s1到t1,s2到t2的距离不超过d1,d2

因为最后s1,t1是连通的,且要破坏掉最多的道路,那么就是求s1到t1之间的最短路

用bfs求出任意两个顶点之间的距离, 如果d[s1][t1]>d1||d[s2][t2]>d2,那么不可能

然后就枚举重叠的区间(就像题解里面说的"H"形一样)

如果枚举区间是1--n,1--i的话,需要交换四次

如果枚举区间是1--n,1--n的话,则只需要交换一次就可以了

看的这一篇题解:http://www.cnblogs.com/qscqesze/p/4487498.html

交换一次的

 1 #include<iostream>  
 2 #include<cstdio>  
 3 #include<cstring> 
 4 #include <cmath> 
 5 #include<stack>
 6 #include<vector>
 7 #include<map> 
 8 #include<set>
 9 #include<queue> 
10 #include<algorithm>  
11 using namespace std;
12 
13 #define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
14 
15 typedef long long LL;
16 const int INF = (1<<30)-1;
17 const int mod=1000000007;
18 const int maxn=5005;
19 
20 int n,m;
21 vector<int> e[maxn];
22 int vis[maxn];
23 int d[maxn][maxn];
24 
25 
26 int main(){
27     scanf("%d %d",&n,&m);
28     for(int i=1;i<=m;i++){
29         int u,v;
30         scanf("%d %d",&u,&v);
31         e[u].push_back(v);
32         e[v].push_back(u);
33     }
34     
35     int s1,t1,d1,s2,t2,d2;
36     scanf("%d %d %d %d %d %d",&s1,&t1,&d1,&s2,&t2,&d2);
37 
38     
39     for(int i=1;i<=n;i++){
40         queue<int> q;
41         memset(vis,0,sizeof(vis));
42         vis[i]=1;
43         q.push(i);
44         
45         while(!q.empty()){
46             int u=q.front();q.pop();
47             
48             for(int j=0;j<e[u].size();j++){
49                 int v=e[u][j];
50                 if(vis[v]) continue;
51                 vis[v]=1;
52                 d[i][v]=d[i][u]+1;
53                 q.push(v);            
54             }
55         }        
56     }
57     
58     if(d[s1][t1]>d1||d[s2][t2]>d2) {
59         puts("-1");
60         return 0;
61     }
62     
63     
64     int ans=d[s1][t1]+d[s2][t2];
65     for(int i=1;i<=n;i++){
66         for(int j=1;j<=n;j++){
67             if(d[s1][i]+d[i][j]+d[j][t1]<=d1&&d[s2][i]+d[i][j]+d[j][t2]<=d2)                
68                 ans=min(ans,d[s1][i]+d[i][j]+d[j][t1]+d[s2][i]+d[j][t2]);
69             
70             if(d[s1][i]+d[i][j]+d[j][t1]<=d1&&d[t2][i]+d[i][j]+d[j][s2]<=d2)
71                 ans=min(ans,d[s1][i]+d[i][j]+d[j][t1]+d[t2][i]+d[j][s2]);        
72         }
73     }
74     printf("%d
",m-ans);
75     return 0;
76 }
View Code

交换四次的

 1 #include<iostream>  
 2 #include<cstdio>  
 3 #include<cstring> 
 4 #include <cmath> 
 5 #include<stack>
 6 #include<vector>
 7 #include<map> 
 8 #include<set>
 9 #include<queue> 
10 #include<algorithm>  
11 using namespace std;
12 
13 #define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
14 
15 typedef long long LL;
16 const int INF = (1<<30)-1;
17 const int mod=1000000007;
18 const int maxn=5005;
19 
20 int n,m;
21 vector<int> e[maxn];
22 int vis[maxn];
23 int d[maxn][maxn];
24 
25 
26 int main(){
27     scanf("%d %d",&n,&m);
28     for(int i=1;i<=m;i++){
29         int u,v;
30         scanf("%d %d",&u,&v);
31         e[u].push_back(v);
32         e[v].push_back(u);
33     }
34     
35     int s1,t1,d1,s2,t2,d2;
36     scanf("%d %d %d %d %d %d",&s1,&t1,&d1,&s2,&t2,&d2);
37 
38     
39     for(int i=1;i<=n;i++){
40         queue<int> q;
41         memset(vis,0,sizeof(vis));
42         vis[i]=1;
43         q.push(i);
44         
45         while(!q.empty()){
46             int u=q.front();q.pop();
47             
48             for(int j=0;j<e[u].size();j++){
49                 int v=e[u][j];
50                 if(vis[v]) continue;
51                 vis[v]=1;
52                 d[i][v]=d[i][u]+1;
53                 q.push(v);            
54             }
55         }        
56     }
57     
58     if(d[s1][t1]>d1||d[s2][t2]>d2) {
59         puts("-1");
60         return 0;
61     }
62     
63     
64     int ans=d[s1][t1]+d[s2][t2];
65     for(int i=1;i<=n;i++){
66         for(int j=1;j<=i;j++){
67             if(d[s1][i]+d[i][j]+d[j][t1]<=d1&&d[s2][i]+d[i][j]+d[j][t2]<=d2)                
68                 ans=min(ans,d[s1][i]+d[i][j]+d[j][t1]+d[s2][i]+d[j][t2]);
69             
70             if(d[s1][i]+d[i][j]+d[j][t1]<=d1&&d[t2][i]+d[i][j]+d[j][s2]<=d2)
71                 ans=min(ans,d[s1][i]+d[i][j]+d[j][t1]+d[t2][i]+d[j][s2]);    
72                 
73             if(d[t1][i]+d[i][j]+d[j][s1]<=d1&&d[s2][i]+d[i][j]+d[j][t2]<=d2)                
74                 ans=min(ans,d[t1][i]+d[i][j]+d[j][s1]+d[s2][i]+d[j][t2]);
75             
76             if(d[t1][i]+d[i][j]+d[j][s1]<=d1&&d[t2][i]+d[i][j]+d[j][s2]<=d2)
77                 ans=min(ans,d[t1][i]+d[i][j]+d[j][s1]+d[t2][i]+d[j][s2]);            
78         }
79     }
80     printf("%d
",m-ans);
81     return 0;
82 }
View Code

加油---g00000000----

原文地址:https://www.cnblogs.com/wuyuewoniu/p/4491935.html