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
  • 相关阅读:
    linux之awk命令
    HDU 2097 Sky数 进制转换
    HDU 2077 汉诺塔IV
    HDU 2094 产生冠军 dfs加map容器
    HDU 2073 叠框
    HDU 2083 简易版之最短距离
    HDU 2063 过山车 二分匹配
    天梯 1014 装箱问题
    天梯 1214 线段覆盖
    天梯 1098 均分纸牌
  • 原文地址:https://www.cnblogs.com/Wwb123/p/11221089.html
Copyright © 2011-2022 走看看