zoukankan      html  css  js  c++  java
  • [APIO2009-C]抢掠计划

    题:https://www.cometoj.com/problem/0461

    分析:求边双,最后求多汇点最长路

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #define pb push_back
    using namespace std;
    const int M=5e5+5;
    int sum[M],book[M],jiu[M],head[M],dfn[M],low[M],vis[M],sta[M],cmp[M],dis[M],val[M],newval[M],tot,top,cnt,num;
    vector<int>g[M];
    struct node{
        int v,w,nextt;
    }e[M];
    void tarjan(int u,int f){
        dfn[u]=low[u]=++cnt;
        sta[++top]=u;
        vis[u]=1;
        for(int i=0;i<g[u].size();i++){
            int v=g[u][i];
            if(v==f)
                continue;
            if(!dfn[v]){
                tarjan(v,u);
                low[u]=min(low[u],low[v]);
            }
            else if(vis[v])
                low[u]=min(low[u],dfn[v]);
        }
        if(low[u]==dfn[u]){
            cmp[u]=++tot;
            int countt=val[u];
            vis[u]=0;
            int len=top;
            while(sta[top]!=u){
                countt+=val[sta[top]];
                cmp[sta[top]]=tot;
                vis[sta[top--]]=0;
            }
            top--;
            sum[tot]=len-top;
            newval[tot]=countt;
        }
    }
    void addedge(int u,int v,int w){
        e[num].v=v;
        e[num].w=w;
        e[num].nextt=head[u];
        head[u]=num++;
    }
    int spfa(int s,int t){
        for(int i=s;i<=t;i++)
            dis[i]=0,vis[i]=0;
        queue<int>que;
        que.push(s);
        while(!que.empty()){
            int u=que.front();
            que.pop();
            vis[u]=0;
            for(int i=head[u];~i;i=e[i].nextt){
                int v=e[i].v;
                if(dis[v]<dis[u]+e[i].w){
                    dis[v]=dis[u]+e[i].w;
                    if(!vis[v])
                        vis[v]=1,que.push(v);
    
                }
            }
        }
        return dis[t];
    }
    int main(){
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=0;i<=n;i++)
            head[i]=-1;
        for(int i=1,u,v;i<=m;i++){
            scanf("%d%d",&u,&v);
            g[u].pb(v);
        }
        for(int i=1;i<=n;i++)
            scanf("%d",&val[i]);
        int s,p;
        scanf("%d%d",&s,&p);
        for(int i=1;i<=p;i++)
            scanf("%d",&jiu[i]);
        for(int i=1;i<=n;i++)
            if(!dfn[i])
                tarjan(i,-1);
        s=cmp[s];
        int t=tot+1;
        for(int i=1;i<=n;i++)
            for(int j=0,v;j<g[i].size();j++){
                v=g[i][j];
                if(cmp[i]!=cmp[v]){
        //m            cout<<cmp[i]<<"!!!!!"<<cmp[v]<<"!!!!"<<newval[cmp[i]]<<endl;
                    addedge(cmp[i],cmp[v],newval[cmp[i]]);
                }
            }
        for(int i=1;i<=p;i++){
            if(book[cmp[jiu[i]]]==1)
                continue;
            book[cmp[jiu[i]]]=1;
            int w=newval[cmp[jiu[i]]];
        //    if(sum[cmp[jiu[i]]]>1)
        //        w=0;
        //        cout<<cmp[jiu[i]]<<"!!!!!"<<t<<"!!!!"<<w<<endl;
            addedge(cmp[jiu[i]],t,w);
        }
        printf("%d
    ",spfa(s,t));
    }
    View Code
  • 相关阅读:
    mysql 注意事项 PreparedStatement 对比 statement
    Dbutils commons-dbutils-1.3
    C3P0 mysql 5.7
    servlet-应用mysql-1
    javabean 用integer 而不是int
    servlet-1
    servlet 路径 编码 问题
    mac tomcat 9.0
    case end 的用法
    自定义抛出异常
  • 原文地址:https://www.cnblogs.com/starve/p/11614353.html
Copyright © 2011-2022 走看看