• Codeforce544C Writing Code


    题意:输入n个点,m条无向边(n,m<3000),接着输入s1, t1, l1, s2, t2, l2问最多可以删多少条边,使得s1到t1距离最多为l1, s2到t2距离最多为l2

    题解:可以发现有三种情况

    第一种是不可能情况

    第二种是s1->t1, s2->t2没有重复的边,那么答案就是m-(d[s1][t1]+d[s2][t2])

    第三种是有重复的边,这时候会形成一个类似H形状的图,只要枚举中间重复的边,计算答案就可以

    注意这里不能用floyed来算最短路,O(n^3),因为边较少且为正,可以n次dijstra, 复杂度O(VE + V*V*logV)

    或者n次bfs也可以

    #include <bits/stdc++.h>
    #define maxn 3010
    #define INF 0x3f3f3f3f
    typedef long long ll;
    using namespace std;
    struct edge{
        int from,to,dist;
    };
    struct node{
        int d,u;
        bool operator<(const node& a) const{
            return d>a.d;
        }
    };
    int d[maxn][maxn];
    struct dij{
        int n,m;
        vector<int >G[maxn];
        vector<edge>edges;
        bool done[maxn];
        int p[maxn];
        void init(int x){
            n = x;
            for(int i=1;i<=n;i++) G[i].clear();
            edges.clear();
        }
        void add(int a,int b,int w){
            edges.push_back((edge){a,b,w});
            m = edges.size();
            G[a].push_back(m-1);
        }
        void dijstra(int st){//计算最短路
            for(int i=1;i<=n;i++) d[st][i] = INF;
            memset(done, 0, sizeof(done));
            d[st][st] = 0;
            priority_queue<node>q;
            q.push((node){0, st});
            while(!q.empty()){
                node fi = q.top();q.pop();
                int u = fi.u;
                if(done[u]) continue;
                done[u] = 1;
                for(int i=0;i<G[u].size();i++){
                    edge& e = edges[G[u][i]];
                    if(e.dist+d[st][u]<d[st][e.to]){
                        d[st][e.to] = d[st][u]+e.dist;
                        p[e.to] = G[u][i];
                        q.push((node){d[st][e.to], e.to});
                    }
                }
            }
        }
    }dj;
    int main(){
        int n, m, a, b, s1, t1, l1, s2, t2, l2;
        scanf("%d%d", &n, &m);
        dj.init(n);
        for(int i=0;i<m;i++){
            scanf("%d%d", &a, &b);
            dj.add(a, b, 1);
            dj.add(b, a, 1);
        }
        scanf("%d%d%d", &s1, &t1, &l1);
        scanf("%d%d%d", &s2, &t2, &l2);
        for(int i=1;i<=n;i++)
            dj.dijstra(i);
        if(d[s1][t1] > l1||d[s2][t2] > l2) printf("-1
    ");
        else{
            int ans = d[s1][t1]+d[s2][t2];
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    if(d[s1][i]+d[i][j]+d[j][t1]<=l1&&d[s2][i]+d[i][j]+d[j][t2]<=l2)
                        ans = min(ans, d[i][j]+d[s1][i]+d[j][t1]+d[s2][i]+d[j][t2]);
                    if(d[s1][i]+d[i][j]+d[j][t1]<=l1&&d[s2][j]+d[j][i]+d[i][t2]<=l2)
                        ans = min(ans, d[i][j]+d[s1][i]+d[j][t1]+d[s2][j]+d[i][t2]);
                }
            }
            printf("%d
    ", m-ans);
        }
        return 0;
    }
  • 相关阅读:
    C++报错undefined reference to vtable处理
    emplace_back无法支持<braceenclosed initializer list>吗?
    使用proxychains代理应用
    EasyExcel快速读写Excel数据
    解决SpringBoot跨域的三种方式
    SQL Server 锁(LOCK)大全
    MySQL预处理语句PREPARE、EXECUTE、DEALLOCATE使用大全
    C# 自定义泛型二维数组
    C# 一维数组与二维数组相互转换
    C#枚举高级应用
  • 原文地址:https://www.cnblogs.com/Noevon/p/8430295.html
Copyright © 2020-2023  润新知