zoukankan      html  css  js  c++  java
  • P4300 [AHOI2008]上学路线

    题目链接

    题解:

    看到输出的第一行,显然就是最短路,n<=500随便乱搞都可以。而我们看他要使删边过后的代价最小。那么考虑怎样删边,就是删去1-n的最短路上的边。一开始我不知道删边怎么处理,看了题解才知道,这是用的是最基础的网络流。我们先枚举所有点,然后可以把在每一个在最短路上的点建一个新图,然后这个新图的最大流(最小割)即为答案。用dinic算法即可。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1100007;
    const int inf=0x7fffffff;
    struct node{
        int nxt,to,val,cut;
    }edge[maxn*3];
    int head[maxn],cnt;
    int cur[maxn];
    struct node2{
        int nxt,to,val;
    }edge2[maxn*3];
    void add(int x,int y,int v,int w){
        edge[++cnt].nxt=head[x];
        edge[cnt].to=y;
        edge[cnt].val=v;
        edge[cnt].cut=w;
        head[x]=cnt;
    }
    int head2[maxn],tot=1;//改成1就行了?? 
    void newadd(int x,int y,int v){
        edge2[++tot].nxt=head2[x];
        edge2[tot].to=y;
        edge2[tot].val=v;
        head2[x]=tot;
    }
    priority_queue<pair<int,int> >que;
    bool vis[maxn];
    int dis[maxn];
    int n,m;
    int ans1;
    int p[maxn],q[maxn],t[maxn],c[maxn]; 
    void dijkstra(int x){
        memset(vis,false,sizeof(vis));
        memset(dis,0x3f,sizeof(dis));
        que.push(make_pair(0,x));
        dis[x]=0;
        while(!que.empty()){
            int u=que.top().second;
            que.pop();
            if(vis[u]) continue;
            vis[u]=true;
            for(int i=head[u];i;i=edge[i].nxt){
                int go=edge[i].to;
                if(dis[go]>dis[u]+edge[i].val){
                    dis[go]=dis[u]+edge[i].val;
                    que.push(make_pair(-dis[go],go));
                }
            }
        }
    }
    int dep[maxn];
    queue<int> qq;
    int bfs(){    
        qq.push(1);
        memset(dep,0,sizeof(dep));
        dep[1]=1;
        while(!qq.empty()){
            int u=qq.front();
            qq.pop();
            for(int i=head2[u];i;i=edge2[i].nxt){
                int v=edge2[i].to;
                if(edge2[i].val&&!dep[v]){
                    dep[v]=dep[u]+1;
                    qq.push(v);
                }
            }
        }
        return dep[n];
    }
    int dfs(int now,int flow){
        if(now==n) return flow;
        for(int i=head2[now];i;i=edge2[i].nxt){
            int go=edge2[i].to;
            if(dep[go]==dep[now]+1&&edge2[i].val){
                int temp=dfs(go,min(flow,edge2[i].val));
                if(temp){
                    edge2[i].val-=temp;
                    edge2[i^1].val+=temp;
                    return temp;
                }
            }
        }
        return 0;
    }
    int dinic(){
        int ans=0,tmp;
        while(bfs()){
            while(tmp=dfs(1,inf)) ans+=tmp;
        }
        return ans;
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            scanf("%d%d%d%d",&p[i],&q[i],&t[i],&c[i]);
            add(p[i],q[i],t[i],c[i]);add(q[i],p[i],t[i],c[i]);
        }
        dijkstra(1);
        ans1=dis[n];
        for(int i=1;i<=n;i++){
            for(int j=head[i];j;j=edge[j].nxt){
                int go=edge[j].to;
                if(dis[go]==dis[i]+edge[j].val){
                    newadd(i,go,edge[j].cut);
                    newadd(go,i,0);
                }
            }
        }
        printf("%d
    %d
    ",ans1,dinic());
        return 0;
    }
    View Code
  • 相关阅读:
    VIM中保存编辑的只读文件
    ElasticSearch 入门
    NET Core实现OAuth2.0的ResourceOwnerPassword和ClientCredentials模式
    visual studio for mac的安装初体验
    分库分表
    Oracle执行计划
    mybatis批量update(mysql)
    查看mysql字符集及修改表结构--表字符集,字段字符集
    13.1.17 CREATE TABLE Syntax
    10.1.5 Connection Character Sets and Collations
  • 原文地址:https://www.cnblogs.com/LJB666/p/11650795.html
Copyright © 2011-2022 走看看