zoukankan      html  css  js  c++  java
  • 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----

  • 相关阅读:
    学习过程
    一个链表中包含环,请找出该链表的环的入口结点
    归并排序-递归实现
    31、求整数范围中1的个数
    冒泡排序
    常用的端口对应的协议
    数值的整数次方
    二分查找(折半查找)
    用两个队列模拟栈的弹出和输入
    Java源码-HashMap(jdk1.8)
  • 原文地址:https://www.cnblogs.com/wuyuewoniu/p/4491935.html
Copyright © 2011-2022 走看看