zoukankan      html  css  js  c++  java
  • 7.16T2

    这是个水题+模板题,我就是想记录一下这道题在我的考试题中出现过

    一句话题解:Tarjan缩点,然后贪心转移

    其实关于这个贪心还是要提两句的,我们来证明一下这题贪心的正确性

    因为这道题要求每个点都必须被到达,那么我们就可以用每一个点去转移给他的子节点,如果一个子节点有多个父节点,那你在这些父节点中选一个权值最小的,一定可以通过这条边从父节点走到子节点,不会被其他节点选择的路径影响且不会对其他节点的路径选择造成影响,所以贪心一定是正确的

    说实话,用贪心,贪心的正确性要想,要证,但是如果你考试的时候实在不能严格的证明出来,但是又举不出反例,想不到其他解决方法,那有时候选择贪心得部分分也是可以的,再说了,万一贪心就是正解呢,当然了,平常做题一定要花时间去想去证明,知其然知其所以然嘛

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<stack>
     4 #include<cstring>
     5 #define maxn 50010
     6 #define maxm 100100
     7 #define ll long long
     8 using namespace std;
     9 int n,m,js,tot,cnt,j;
    10 ll ans;
    11 int head[maxn],to[maxm],xia[maxm],wh[maxm];
    12 int dfn[maxn],low[maxn],pd[maxn],ss[maxn];
    13 int h[maxn],t[maxm],x[maxm],w[maxm];
    14 int f[maxn];
    15 stack <int> s;
    16 int read()
    17 {
    18     int e=0,f=1;
    19     char ch=getchar();
    20     while(ch<'0'||ch>'9')
    21     {
    22         if(ch=='-')  f=-1;
    23         ch=getchar();
    24     }
    25     while(ch>='0'&&ch<='9')  {e=(e<<3)+(e<<1)+(ch-48);  ch=getchar();}
    26     return e*f;
    27 }
    28 void clear()
    29 {
    30     js=0;  tot=0;  cnt=0;  j=0;  ans=0;
    31     while(s.empty()==false)  s.pop();
    32     memset(head,0,sizeof(head));  memset(to,0,sizeof(to));  memset(xia,0,sizeof(xia));
    33     memset(wh,0,sizeof(wh));  memset(dfn,0,sizeof(dfn));  memset(low,0,sizeof(low));
    34     memset(pd,0,sizeof(pd));  memset(ss,0,sizeof(ss));  memset(h,0,sizeof(h));
    35     memset(t,0,sizeof(t));  memset(x,0,sizeof(x));  memset(w,0,sizeof(w));
    36     memset(f,0x7f,sizeof(f));
    37 }
    38 void add(int x,int y,int z)
    39 {
    40     to[++js]=y;  xia[js]=head[x];  wh[js]=z;  head[x]=js;
    41 }
    42 void ADD(int a,int b,int c)
    43 {
    44     t[++j]=b;  x[j]=h[a];  w[j]=c;  h[a]=j;
    45 }
    46 void tarjan(int x)
    47 {
    48     dfn[x]=low[x]=++tot;  s.push(x);  pd[x]=1;
    49     for(int i=head[x];i;i=xia[i])
    50     {
    51         int ls=to[i];
    52         if(dfn[ls]==0)  {tarjan(ls);  low[x]=min(low[x],low[ls]);}
    53         else if(pd[ls]==1)  low[x]=min(low[x],dfn[ls]);
    54     }
    55     if(low[x]==dfn[x])
    56     {
    57         int y;  cnt++;
    58         do  {y=s.top();  s.pop();  pd[y]=0;  ss[y]=cnt;}
    59         while(y!=x);
    60     }
    61 }
    62 void dfs(int a)
    63 {
    64     for(int i=h[a];i;i=x[i])  {int ls=t[i];  f[ls]=min(f[ls],w[i]);  dfs(ls);}
    65 }
    66 int main()
    67 {
    68     while(1)
    69     {
    70         n=read();  m=read();
    71         if(n==0&&m==0)  break;
    72         clear();
    73         for(int i=1;i<=m;++i)  {int o=read(),p=read(),q=read();  add(o+1,p+1,q);}
    74         for(int i=1;i<=n;++i)
    75             if(dfn[i]==0)  tarjan(i);
    76         for(int i=1;i<=n;++i)
    77             for(int j=head[i];j;j=xia[j])
    78             {
    79                 int ls=to[j];
    80                 if(ss[i]==ss[ls])  continue;
    81                 ADD(ss[i],ss[ls],wh[j]);
    82             }
    83         dfs(ss[1]);
    84         for(int i=1;i<=cnt;++i)
    85         {
    86             if(ss[1]==i)  continue;
    87             ans+=(ll)f[i];
    88         }
    89         printf("%lld
    ",ans);
    90     }
    91     return 0;
    92 }
    View Code
  • 相关阅读:
    IT经典书籍——Head First系列【推荐】
    IT经典书籍——Head First系列【推荐】
    使用JSP实现用户登录
    使用JSP实现用户登录
    【知乎精选】如何面试一个产品经理?如何判断一个产品经理是否是一个很牛的产品经理?
    淘宝API总结
    「用户标签」在数据库设计时应该如何存储?
    【爬虫集合】抖音API分析
    商业架构体系
    短视频带货
  • 原文地址:https://www.cnblogs.com/hzjuruo/p/11201957.html
Copyright © 2011-2022 走看看