zoukankan      html  css  js  c++  java
  • [Codeforces 507E] Breaking Good

    [题目链接]

             https://codeforces.com/contest/507/problem/E

    [算法]

            首先BFS求出1到其余点的最短路 , N到其余点的最短路,记为distA[]和distB[]

            显然 , 我们只需最大化求出的最短路上没有被破坏的边即可 , 不妨用f[i]表示现在在城市i , distA[i] + distB[i] = distA[N] , 最多还能经过几条没有被破坏的边 

            记忆化搜索即可

            时间复杂度 : O(N)

    [代码]

            

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN = 1e5 + 10;
    const int inf = 1e9;
    
    struct edge
    {
            int to , state , id , nxt;
    } e[MAXN << 1];
    struct info
    {
            int u , v , ns;
    } res[MAXN];
    
    int n , m , tot;
    int u[MAXN],v[MAXN],state[MAXN],head[MAXN],dista[MAXN],distb[MAXN],f[MAXN];
    pair<int,int> nxt[MAXN];
    bool visited[MAXN];
    
    template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
    template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
    template <typename T> inline void read(T &x)
    {
        T f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
    }
    inline void addedge(int u,int v,int s,int id)
    {
            tot++;
            e[tot] = (edge){v,s,id,head[u]};
            head[u] = tot; 
    } 
    inline void bfs1(int s)
    {
            queue< int > q;
            dista[s] = 0;
            visited[s] = true;
            q.push(s);
            while (!q.empty())        
            {
                    int cur = q.front();
                    q.pop();
                    for (int i = head[cur]; i; i = e[i].nxt)
                    {
                            int v = e[i].to;
                            if (!visited[v])
                            {
                                    visited[v] = true;
                                    dista[v] = dista[cur] + 1;
                                    q.push(v);
                            }
                    }
            }
    }
    inline void bfs2(int s)
    {
            queue< int > q;
            distb[s] = 0;
            visited[s] = true;
            q.push(s);
            while (!q.empty())
            {
                    int cur = q.front();
                    q.pop();
                    for (int i = head[cur]; i; i = e[i].nxt)
                    {
                            int v = e[i].to;
                            if (!visited[v])
                            {
                                    visited[v] = true;
                                    distb[v] = distb[cur] + 1;
                                    q.push(v);
                            }
                    }
            }
    }
    inline int dp(int u)
    {
            if (u == n) return f[u] = 0;
            if (f[u] != -1) return f[u];
            f[u] = -inf;
            for (int i = head[u]; i; i = e[i].nxt)
            {
                    int v = e[i].to , st = e[i].state , id = e[i].id , value;
                    if (dista[u] + distb[v] + 1 != dista[n]) continue;
                    if (st == 1) 
                    {
                            value = dp(v) + 1;
                            if (value > f[u]) 
                            {
                                    f[u] = value;
                                    nxt[u] = make_pair(v,id);
                            }
                    } else 
                    {
                            value = dp(v);
                            if (value > f[u])
                            {
                                    f[u] = value;
                                    nxt[u] = make_pair(v,id);
                            }
                    }
            }
            return f[u];
    }
    inline void getpath(vector<int> &a)
    {
            int now = 1;
            while (nxt[now].first)
            {
                    a.push_back(nxt[now].second);
                    now = nxt[now].first;        
            }        
    }
    
    int main()
    {
            
            read(n); read(m);
            for (int i = 1; i <= m; i++)
            {
                    read(u[i]); read(v[i]); read(state[i]);
                    addedge(u[i],v[i],state[i],i);    
                    addedge(v[i],u[i],state[i],i);    
            }
            memset(visited,false,sizeof(visited));
            bfs1(1);
            memset(visited,false,sizeof(visited));
            bfs2(n);
            memset(f,255,sizeof(f));
            dp(1);
            vector<int> path;
            getpath(path);
            int len = 0;
            memset(visited,false,sizeof(visited));
            for (unsigned i = 0; i < path.size(); i++)
            {
                    visited[path[i]] = true;
                    if (state[path[i]] == 0) res[++len] = (info){u[path[i]],v[path[i]],1};        
            }
            for (int i = 1; i <= m; i++)
            {
                    if (!visited[i] && state[i])
                            res[++len] = (info){u[i],v[i],0};
            }
            printf("%d
    ",len);
            for (int i = 1; i <= len; i++) printf("%d %d %d
    ",res[i].u,res[i].v,res[i].ns);
            
            return 0;
        
    }
  • 相关阅读:
    (24)码表
    (23)IO之打印流 PrintStream & Printwriter
    (22)Properties,这不会Io流中的类,但是通常和IO流中的一些流配合使用
    (21)IO流之对象的序列化和反序列化流ObjectOutputStream和ObjectInputStream
    (20)IO流之SequenceInputStream 序列流
    01.vue基础
    02.1插值操作-Mustache语法
    jQuery对节点的增删改查和一些常用的逻辑处理
    递归 阶乘
    电脑远程连接
  • 原文地址:https://www.cnblogs.com/evenbao/p/9745680.html
Copyright © 2011-2022 走看看