题意:给出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 }
交换四次的
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 }
加油---g00000000----