zoukankan      html  css  js  c++  java
  • 【NOIP模拟赛(六)】花园的守护之神(greendam)-最短路-最大流最小割

    Problem Greemdam

    题目大意

    给一个图$G=(V,E)$,求要使这个图的最短路增长所需要增加的最小权值的值。

    Solution

    既然是要求这个玩意儿,我们可以排除除了最短路以外的所有路径,因为这些是无用的。

    对于每一条最短路路径,如果这条路径与任意一个最短路路径有相同的一条边,

    那我们只需要在这条边权值加一就可以保证这两个最短路都增加了。

    所以我们转化为求不相交边的最短路路径数,

    其实就是这个图的最小割。

    我们给最短路的图每个边附权值为1(因为前权值是无用的),

    跑一遍最大流即可。

    Dijkstra跑的要比spfa快。最好加个优先队列优化。

    Datamaker

    首先声明这个datamaker是无用的,最多只能让你看看极限数据跑多久。

    因为随机出来数据所有的答案都是1。

     1 #include <iostream>
     2 #include <ctime>
     3 #include <cstdio>
     4 #define MAXN 1000
     5 #define MAXM 500000
     6 #define MAXC 1000000
     7 using namespace std;
     8 int main(){
     9     freopen("b.in","w",stdout);
    10     srand(time(NULL));
    11     int st=rand()%(MAXN-1)+1,ed=rand()%(MAXN-1)+1;
    12     while(st==ed)ed=rand()%(MAXN-1)+1;
    13     printf("%d %d %d %d
    ",MAXN,MAXM,st,ed);
    14     for(int i=1;i<=MAXM;i++)
    15         printf("%d %d %d
    ",rand()%(MAXN-1)+1,rand()%(MAXN-1)+1,rand()%(MAXC-1)+1);
    16 }

    AC Code

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <queue>
     6 #define INF 1e15
     7 #define ll long long
     8 using namespace std;
     9 struct node{
    10     int to,next,from;
    11     ll w;
    12 }e[1000010];
    13 struct nodee{
    14     int to,next,w;
    15 }a[1000010];
    16 typedef pair<int,int> pa;
    17 int n,m,st,ed,u,v,ans=0,tot=0,tott=1;
    18 int h[1010],hh[1010],dis[1010],q[1010];
    19 ll w,d[1010];
    20 bool visit[1010];
    21 void add(int u,int v,ll w){
    22     e[++tot].to=v;e[tot].next=h[u];
    23     h[u]=tot;e[tot].w=w;e[tot].from=u;
    24     e[++tot].to=u;e[tot].next=h[v];
    25     h[v]=tot;e[tot].w=w;e[tot].from=v;
    26 }
    27 void insr(int u,int v,int w){
    28     a[++tott].to=v;a[tott].next=hh[u];
    29     hh[u]=tott;a[tott].w=w;
    30     a[++tott].to=u;a[tott].next=hh[v];
    31     hh[v]=tott;a[tott].w=0;
    32 }
    33 bool bfs(){
    34     int head=0,tail=1;
    35     memset(dis,-1,sizeof(dis));
    36     dis[st]=0;q[0]=st;
    37     while(head!=tail){
    38         int now=q[head];
    39         for(int i=hh[now];~i;i=a[i].next)
    40             if(a[i].w&&dis[a[i].to]==-1){
    41                 dis[a[i].to]=dis[now]+1;
    42                 q[tail++]=a[i].to;
    43             }
    44         head++;
    45     }
    46     return dis[ed]!=-1;
    47 }
    48 int dfs(int now,int flow){
    49     if(now==ed)return flow;
    50     int w,used=0;
    51     for(int i=hh[now];~i;i=a[i].next)
    52         if(dis[now]+1==dis[a[i].to]){
    53             w=dfs(a[i].to,min(a[i].w,flow-used));
    54             a[i].w-=w;
    55             a[i^1].w+=w;
    56             used+=w;
    57             if(used==flow)return flow;
    58         }
    59     if(!used)dis[now]=-1;
    60     return used;
    61 }
    62 void dijkstra(){
    63     memset(visit,0,sizeof(visit));
    64     for(int i=1;i<=n;i++)d[i]=INF;
    65     d[st]=0;
    66     priority_queue<pa,vector<pa>,greater<pa>> q;
    67     q.push(make_pair(0,st));
    68     while(!q.empty()){
    69         int now=q.top().second;
    70         q.pop();
    71         if(!visit[now]){
    72             visit[now]=1;
    73             for(int i=h[now];~i;i=e[i].next)
    74                 if(d[now]+e[i].w<d[e[i].to]){
    75                     d[e[i].to]=d[now]+e[i].w;
    76                     q.push(make_pair(d[e[i].to],e[i].to));
    77                 }
    78         }
    79     }
    80 }
    81 int main(){
    82     //freopen("b.in","r",stdin);
    83     //freopen("b.out","w",stdout);
    84     memset(h,-1,sizeof(h));
    85     memset(hh,-1,sizeof(hh));
    86     scanf("%d%d%d%d",&n,&m,&st,&ed);
    87     for(int i=1;i<=m;i++){
    88         scanf("%d%d%lld",&u,&v,&w);
    89         add(u,v,w);
    90     }
    91     dijkstra();
    92     for(int i=1;i<=tot;i++)
    93         if(d[e[i].from]+e[i].w==d[e[i].to])
    94             insr(e[i].from,e[i].to,1);
    95     while(bfs())
    96         ans+=dfs(st,1e9);
    97     printf("%d",ans);
    98 }
  • 相关阅读:
    进度条
    打开文件的功能代码 JFileChooser
    我对JAVA的初认知
    集合之五:Set接口
    集合之四:List接口
    集合之三:泛型
    Maven web项目(简单的表单提交) 搭建(eclipse)
    集合之二:迭代器
    集合之一:集合概述
    java的函数
  • 原文地址:https://www.cnblogs.com/skylynf/p/7565238.html
Copyright © 2011-2022 走看看