• 【2017杭二联考】 图的有向环


    P2555 - 【2017杭二联考】图的有向环

    Description

    题目背景: 
    幻想乡的亡灵公主,西行寺幽幽子,在幻想乡很受欢迎,经常有妖怪来拜访她,但是幽 幽子并不喜欢被打扰,她希望从白玉楼出发,散步之后再回到白玉楼,同时路上遇到的妖怪 越少越好(有趣的是道路两边的妖怪数量并不相同,分别从两个方向经过同一条道路遇到的 妖怪数量是不同的)。当然,作为冥界的公主,她是不会重复经过同一条道路的。

    问题描述: 
    给定一个有 n 个点 m 条无向边的图,每条无向边最多只能经过一次。 
    对于边(ui, vi), 从 ui 到 vi 的代价为 ai,从 vi 到 ui 的代价为 bi,其中 ai 和 bi 不一定相等。 求一个包 含 1 号点的有向环,使得环上代价之和最小。(保证图中没有重边和自环。)

    Input

    第一行两个个正整数 n,m,点数和边数。 
    接下来 m 行,每行四个正整数,ui,vi,ai,bi。 
    从 ui 到 vi 的代价为 ai,从 vi 到 ui 的代价为 bi 。

    Output

    输出一行,一个整数,如果有解输出最小代价,否则输出''-1''(不含引号)。

    Sample Input

    3 3 
    1 2 4 3 
    2 3 4 2 
    1 3 1 1

    Sample Output

    6

    Hint

    数据范围: 
    对于前 15% 的数据,3 <= n <= 20, 3 <= m <= 20 
    对于前 30% 的数据,3 <= n <= 150, 3 <= m <= 2500 
    对于前 70% 的数据,3 <= n <= 5000, 3 <= m <= 10^4 
    对于 100% 的数据, 3 <= n <= 30000 , 3 <= m <= 10^5 , 1<=ui, vi <= n,1 <= ai, bi <= 10^4。 
    保证图中没有重边,即不存在 i <> j,使得 ui = uj,vi = vj。 
    保证图中没有自环,即 ui <> vi。

    Source

    图论,最短路

     
    枚举与一号点相连的每一条边,再跑SPFA,min(枚举的边的长度+dis[1])即为答案,但是要注意剪枝和优化.
     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<vector>
     8 #include<stack>
     9 #include<queue>
    10 #include<map>
    11 #define RG register
    12 #define IL inline
    13 #define pi acos(-1.0)
    14 #define ll long long 
    15 using namespace std;
    16 struct edge{
    17   int first,nxt,to,w;
    18 };
    19 edge a[200050];
    20 int n,m,num,minn;
    21 int f[200050],dis[100050];
    22 bool pan[100050];
    23 void add(int l,int r,int w){
    24   a[++num].to=r;
    25   a[num].w=w;
    26   a[num].nxt=a[l].first;
    27   a[l].first=num;
    28 }
    29 inline void  spfa(int S,int w){
    30   for(RG int i=1;i<=n;i++) dis[i]=999999999;
    31   memset(pan,true,sizeof(pan));
    32   queue <int> s;
    33   s.push(S);
    34   dis[S]=w;
    35   while(!s.empty()){
    36     int u=s.front();
    37     s.pop();
    38     pan[u]=true;
    39     if(dis[u]>=minn) continue;
    40     if(u==1) {minn=min(minn,dis[u]);continue;}
    41     for(int i=a[u].first;i;i=a[i].nxt){
    42       if(f[i]) continue;
    43       int v=a[i].to;
    44       if(dis[u]+a[i].w<dis[v]){
    45     dis[v]=dis[u]+a[i].w;
    46     if(pan[v]){
    47       pan[v]=false;
    48       s.push(v);
    49     }
    50       }
    51     }
    52   }
    53 }  
    54 int main() {
    55   scanf("%d%d",&n,&m);
    56   for(int i=1;i<=m;i++){
    57     int u,v,a,b;
    58     scanf("%d%d%d%d",&u,&v,&a,&b);
    59     add(u,v,a),add(v,u,b);
    60   }
    61   minn=999999999;
    62   for(int i=a[1].first;i;i=a[i].nxt){
    63     f[i]=1;
    64     if(i%2==0) f[i-1]=1;
    65     else f[i+1]=1;
    66     spfa(a[i].to,a[i].w);
    67     f[i]=0;
    68     if(i%2==0) f[i-1]=0;
    69     else f[i+1]=0;
    70   }
    71   if(minn==999999999)  printf("-1");
    72   else  printf("%d",minn);
    73   return 0;
    74 }
  • 相关阅读:
    PHP页面静态化
    PHP实现单文件、多文件上传 封装 面向对象实现文件上传
    PHP MYSQL
    MySQL 数据表
    MySQL基础
    DOM事件处理程序-事件对象-键盘事件
    JS--显示类型转换Number—隐式类型转换
    JS的数据类型
    JS属性读写操作+if判断注意事项
    Javascript进阶篇——总结--DOM案例+选项卡效果
  • 原文地址:https://www.cnblogs.com/cjoier-nfy/p/7407349.html
Copyright © 2020-2023  润新知