[Skiing] SCOI2012

题目太长不想放
从1号点开始,只能向高度更低或者相同的点走
可以返回之前走过的点
在经过的点最多的前提下,走过的路径最短为多少

This road sb problem actually changed more than one hour
is really not far from retired, right

The idea is very simple, even to the low side to the high point of each
wide search again to see what the point is achievable

Then run the minimum spanning tree to the new top of FIG.

Change for so long, the most important thing is to see bfs bfs version SPFA no brains to write
the results met with a high degree of ring die can not get out

Suicides bar

#include<bits/stdc++.h>
#define ll long long
#define N 100005
#define M 1000005
using namespace std;

int n,m,u,v,w;
int h[N];
ll canget=0,mindis=0;

struct Edge
{
    int next,to,dis;
}edge[M<<1];
int cnt=0,head[M];

inline void add_edge(int from,int to,int dis)
{
    edge[++cnt].next=head[from];
    edge[cnt].to=to;
    edge[cnt].dis=dis;
    head[from]=cnt;
}

template<class T>inline void read(T &res)
{
    char c;T flag=1;
    while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
    while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
}

struct NewEdge
{
    int u,v,w;
}nedge[M<<1];
int ncnt=0;

//bool vis[N];
//queue<int> q;
//void bfs()
//{
//  vis[1]=1;
//  q.push(1);
//  while(!q.empty())
//  {
//      int u=q.front();q.pop();vis[u]=0;
//      for(register int i=head[u];i;i=edge[i].next)
//      {
//          int v=edge[i].to;
//          nedge[++ncnt].u=u;
//          nedge[ncnt].v=v;
//          nedge[ncnt].w=edge[i].dis;
//          if(!vis[v])
//          {
//              canget++;
//              q.push(v);
//              vis[v]=1;
//          }
//      }
//  }
//}


bool vis[N];
int q[N],qr,ql;
void bfs()
{
    q[++qr]=1;
    vis[1]=1;
    while(ql<qr)
    {
        int u=q[++ql];
        for(register int i=head[u];i;i=edge[i].next)
        {
            int v=edge[i].to;
            nedge[++ncnt].u=u;
            nedge[ncnt].v=v;
            nedge[ncnt].w=edge[i].dis;
            if(!vis[v])
            {
                canget++;
                vis[v]=1;
                q[++qr]=(v);
            }
        }
    }
}

bool cmp(NewEdge a,NewEdge b)
{
    return h[a.v]==h[b.v]?a.w<b.w:h[a.v]>h[b.v];
}

int fa[N];
int find(int x) {return x==fa[x]?x:fa[x]=find(fa[x]);}
void kruskal()
{
    sort(nedge+1,nedge+ncnt+1,cmp);
    for(register int i=1;i<=ncnt;++i)
    {
        int fx=find(nedge[i].u);
        int fy=find(nedge[i].v);
        if(fx!=fy)
        {
            fa[fx]=fy;
            mindis+=nedge[i].w;
        }
    }
}

int main()
{
    read(n);read(m);
    for(register int i=1;i<=n;++i) read(h[i]),fa[i]=i;
    for(register int i=1;i<=m;++i)
    {
        read(u);read(v);read(w);
        if(h[u]>=h[v]) add_edge(u,v,w);
        if(h[u]<=h[v]) add_edge(v,u,w);
    }
    bfs();
    kruskal();
    printf("%lld %lld\n",canget+1,mindis);
    return 0;
}
/*
5 5
8 10 5 4 3
1 2 20
1 3 10
2 4 30
3 4 7
3 5 8
*/

Guess you like

Origin www.cnblogs.com/tqr06/p/11716124.html