zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    序列JSON数据和四种AJAX操作方式
    jquery.validate和jquery.form.js实现表单提交
    JQuery Validate使用总结1:
    HOWTO: Include Base64 Encoded Binary Image Data (data URI scheme) in Inline Cascading Style Sheets (CSS)(转)
    SharePoint 2007 使用4.0 .Net
    动态IP解决方案
    取MS CRM表单的URL
    从Iframe或新开的窗口访问MS CRM 2011(转)
    Toggle or Hidden MS CRM Tab
    Windows 2008下修改域用户密码
  • 原文地址:https://www.cnblogs.com/Noevon/p/8430295.html
Copyright © 2011-2022 走看看