zoukankan      html  css  js  c++  java
  • 【模拟7.19】那一天她离我而去(最短路,估价函数剪枝)

    这题忘记输出-1,wa0了QAQ

    首先这题我先看的第二题数据范围,n==m意味着只有一个环,所以可以用tarjan的算法

    把环判出来,比较简单。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<string>
     5 #include<algorithm>
     6 #include<cmath>
     7 #include<stack>
     8 #include<vector>
     9 #define ll long long
    10 using namespace std;
    11 #define MAXN 80010
    12 #define ps push_back
    13 struct node{int to,n,w;}e[MAXN];int tot=0;int head[MAXN];
    14 void add(int u,int v,int w){e[++tot].to=v;e[tot].n=head[u];e[tot].w=w;head[u]=tot;}
    15 int vis[MAXN],low[MAXN],dfn[MAXN];
    16 vector<int>sum[MAXN];int de=0;
    17 int belong[MAXN];
    18 int n,m;int fa[MAXN];
    19 stack<int>q;int cnt=0;int ans_w=10000000;
    20 void tarjan(int x,int w)
    21 {
    22      low[x]=dfn[x]=++de;vis[x]=1;q.push(x);
    23      for(int i=head[x];i;i=e[i].n)
    24      {
    25         int to=e[i].to;
    26         if(dfn[to]==0)
    27         {
    28             fa[to]=x;   
    29             tarjan(to,w+e[i].w);
    30             low[x]=min(low[x],low[to]);
    31         }
    32         else if(vis[to]&&fa[x]!=to)
    33         {
    34             if(to==1)
    35             {
    36                 ans_w=min(ans_w,w+e[i].w);
    37             }
    38             low[x]=min(low[x],dfn[to]);
    39         }
    40      }
    41      if(dfn[x]==low[x])
    42      {
    43          int top=0;
    44          cnt++;
    45          do
    46          {
    47             top=q.top();q.pop();vis[top]=0;
    48             sum[cnt].ps(top);
    49             belong[top]=cnt;
    50          }
    51          while(x!=top);
    52      }
    53 }
    54 int T;
    55 int main()
    56 {
    57     scanf("%d",&T);
    58     while(T--)
    59     {
    60         ans_w=100000000;
    61         memset(head,0,sizeof(head));tot=0;
    62         memset(vis,0,sizeof(vis));
    63         memset(low,0,sizeof(low));
    64         memset(dfn,0,sizeof(dfn));
    65         scanf("%d%d",&n,&m);       
    66         for(int i=1;i<=m;++i)
    67         {                                              
    68             int x,y,w;
    69             scanf("%d%d%d",&x,&y,&w);
    70             add(x,y,w);add(y,x,w);
    71         }
    72         tarjan(1,0);
    73         for(int x=1;x<=cnt;++x)
    74         {
    75             for(int i=0;i<sum[x].size();++i)
    76             {
    77                 int to=sum[x][i];
    78             }
    79         }
    80         if(ans_w==100000000)printf("-1
    ");
    81         else printf("%d
    ",ans_w);
    82         for(int i=1;i<=cnt;++i)sum[i].clear();
    83         cnt=0;
    84     }
    85 }
    30分代码,神犇不要看

    满分的话听了skyh大佬的讲评后用估价函数剪枝DFS,然后暴力跑

    注意DFS中标记的是边而不是点(想起来tarjan的割桥)

    因为他点可以重复经过,边不能

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<string>
     5 #include<algorithm>
     6 #include<cmath>
     7 #include<stack>
     8 #include<vector>
     9 #include<queue>
    10 #define MAXN 41010
    11 #define ps push_back
    12 #define ll int
    13 using namespace std;
    14 struct node{ll to,n,w;}e[2*MAXN];
    15 ll tot=0;ll head[MAXN];
    16 void add(ll u,ll v,ll w){e[++tot].to=v;e[tot].n=head[u];e[tot].w=w;head[u]=tot;}
    17 bool bian[2*MAXN];
    18 ll dis[MAXN];
    19 priority_queue< pair<ll,ll> >q;
    20 ll ans_w=0;
    21 ll n,m;
    22 void SPFA(ll top)
    23 {
    24     memset(bian,0,sizeof(bian));
    25     dis[top]=0;q.push(make_pair(0,top));bian[top]=1;
    26     while(!q.empty())
    27     {
    28        ll x=q.top().second;q.pop();
    29        for(ll i=head[x];i;i=e[i].n)
    30        {
    31            ll to=e[i].to;
    32            if(dis[to]>dis[x]+e[i].w)
    33            {
    34                dis[to]=dis[x]+e[i].w;
    35                if(bian[to]==0)
    36                {
    37                   q.push(make_pair(-dis[to],to));
    38                   bian[to]=1;
    39                }
    40            }
    41        }
    42     }
    43 }
    44 void DFS(ll x,ll w)
    45 {
    46     if(w+dis[x]>=ans_w)return ;
    47     if(x==1)
    48     {
    49         if(w!=0)
    50         {
    51             ans_w=min(ans_w,w);
    52             return ;
    53         }
    54     }
    55     for(ll i=head[x];i;i=e[i].n)
    56     {
    57        ll to=e[i].to;
    58        if(bian[i]==1)continue;
    59        bian[i]=1;bian[(i^1)]=1;
    60        DFS(to,w+e[i].w);
    61        bian[i]=0;bian[(i^1)]=0;
    62     }
    63 }
    64 ll T;
    65 int main()
    66 {
    67     scanf("%d",&T);
    68     while(T--)
    69     {
    70         ans_w=0x7ffffff;tot=1; 
    71         memset(head,0,sizeof(head));
    72         memset(dis,0x7f,sizeof(dis));
    73         scanf("%d%d",&n,&m);       
    74         for(ll i=1;i<=m;++i)
    75         {                                              
    76            ll x,y,w;
    77            scanf("%d%d%d",&x,&y,&w);
    78            add(x,y,w);add(y,x,w);
    79         }
    80         SPFA(1);
    81         memset(bian,0,sizeof(bian));
    82         DFS(1,0);
    83         if(ans_w==0x7ffffff)
    84           printf("-1
    ");
    85         else
    86           printf("%d
    ",ans_w);
    87     }
    88 }
    View Code
  • 相关阅读:
    MYSQL数据库设计规范与原则
    PHP-CI框架数据库连接默认是长连接,需要注意应用场景
    mysql性能调优与架构设计笔记
    JavaScript学习笔记
    PHP一维数组和二维数字排序整理
    MYSQL常用的Show命令笔记
    设计模式之建造者模式
    设计模式之工厂模式
    设计模式前提篇二(C++编程原则)
    设计模式前提篇一(C++/基础)
  • 原文地址:https://www.cnblogs.com/Wwb123/p/11221089.html
Copyright © 2011-2022 走看看