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\n",m-ans);
75     return 0;
76 }

交换四次的

 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\n",m-ans);
81     return 0;
82 }

加油---g00000000----

时间: 2024-10-10 13:43:54

codeforces 544 D Destroying Roads 【最短路】的相关文章

Codeforces 543B Destroying Roads(最短路)

题意: 给定一个n个点(n<=3000)所有边长为1的图,求最多可以删掉多少条边后,图满足s1到t1的距离小于l1,s2到t2的距离小于l2. Solution: 首先可以分两种情况讨论: 1:假设最后留下的边是互不相交的两条路径.此时的答案是n-s1到t1的最短路径-s2到t2的最短路径. 2:假设最后留下的边有重合的一段,此时只要枚举重合的这一段的起点和终点,就可以判断.注意此时要考虑这两条路径经过枚举的两点的顺序. 限制的条件比较多,可以用来剪枝的条件也很多. 由于所有边的长度为1,用DF

Codeforces Round #302 (Div. 2) D. Destroying Roads 最短路 删边

题目:有n个城镇,m条边权为1的双向边让你破坏最多的道路,使得从s1到t1,从s2到t2的距离分别不超过d1和d2. #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <vector> #include <queue> #include <stack> #in

Codeforces544D:Destroying Roads(最短路)

In some country there are exactly n cities and m bidirectional roads connecting the cities. Cities are numbered with integers from 1 to n. If cities a and b are connected by a road, then in an hour you can go along this road either from city a to cit

CodeForces 567E President and Roads(最短路 + tarjan)

CodeForces 567E President and Roads Description Berland has n cities, the capital is located in city s, and the historic home town of the President is in city t (s?≠?t). The cities are connected by one-way roads, the travel time for each of the road

Codeforces 191C Fools and Roads(树链剖分)

题目链接:Codeforces 191C Fools and Roads 题目大意:给定一个N节点的数,然后有M次操作,每次从u移动到v,问说每条边被移动过的次数. 解题思路:树链剖分维护边,用一个数组标记即可,不需要用线段树. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 1e5 + 5; int N, Q, ne, fir

Codeforces Round #Pi (Div. 2) E. President and Roads (最短路+强连通求割边)

题目地址:codeforces #pi (DIV2) E 题目很水..就是先求两边最短路,然后把可能为最短路的边挑出来,然后判断是否yes只需要转化成无向图跑一遍tarjan,找出割边,割边就是yes,然后剩下的边就让它的值为最短路-1就行了,如果-1后变成了非正数,就是no. 但是!!!居然卡spfa!!那是不是说cf以后就不能用可以卡的算法了..完全可以出组数据来卡这些算法...比如spfa,isap... 于是为了这题,又看了一遍迪杰斯特拉算法.. 代码如下: #include <cstd

【poj 1724】 ROADS 最短路(dijkstra+优先队列)

ROADS Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12436 Accepted: 4591 Description N cities named with numbers 1 - N are connected with one-way roads. Each road has two parameters associated with it : the road length and the toll that

codeforces 144 D. Missile Silos 最短路

链接:http://codeforces.com/problemset/problem/144/D D. Missile Silos time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output A country called Berland consists of n cities, numbered with integer numb

Codeforces 449B Jzzhu and Cities(最短路)

题目链接:Codeforces 449B Jzzhu and Cities 题目大意:Jzzhu是一个国家的总统,这个国家有N座城市,以1为首都,已经存在了M条公路,给定M条路.并且还有K条铁轨,铁轨均有首都出发,连接si,距离为yi.现在Jzzhu想要节省经费,拆除一些铁轨,问说最多能拆除多少个铁轨,要求每座城市与首都的最短距离不变. 解题思路:最短路,多加一个标记数组,每个si标记1,如果这些点的最短距离被更新,则将对应si的标记清为0,最后统计一下剩余的标记,即为不能拆除的铁轨. #inc