题目描述
a180285非常喜欢滑雪。他来到一座雪山,这里分布着 MM 条供滑行的轨道和 NN 个轨道之间的交点(同时也是景点),而且每个景点都有一编号 ii ( 1 le i le N1≤i≤N )和一高度 H_iHi 。a180285能从景点 ii 滑到景点 jj 当且仅当存在一条 ii 和 jj 之间的边,且 ii 的高度不小于 jj 。 与其他滑雪爱好者不同,a180285喜欢用最短的滑行路径去访问尽量多的景点。如果仅仅访问一条路径上的景点,他会觉得数量太少。于是a180285拿出了他随身携带的时间胶囊。这是一种很神奇的药物,吃下之后可以立即回到上个经过的景点(不用移动也不被认为是a180285 滑行的距离)。请注意,这种神奇的药物是可以连续食用的,即能够回到较长时间之前到过的景点(比如上上个经过的景点和上上上个经过的景点)。 现在,a180285站在 11 号景点望着山下的目标,心潮澎湃。他十分想知道在不考虑时间胶囊消耗的情况下,以最短滑行距离滑到尽量多的景点的方案(即满足经过景点数最大的前提下使得滑行总距离最小)。你能帮他求出最短距离和景点数吗?
输入输出格式
输入格式:
输入的第一行是两个整数 N,MN,M 。
接下来 11 行有 NN 个整数 H_iHi ,分别表示每个景点的高度。
接下来 MM 行,表示各个景点之间轨道分布的情况。每行 33 个整数, U_i,V_i,K_iUi,Vi,Ki 。表示编号为 U_iUi 的景点和编号为 V_iVi 的景点之间有一条长度为 K_iKi 的轨道。
输出格式:
输出一行,表示a180285最多能到达多少个景点,以及此时最短的滑行距离总和。
输入输出样例
3 3 3 2 1 1 2 1 2 3 1 1 3 10
3 2
说明
【数据范围】
对于 30\%30% 的数据,保证 1 le N le 20001≤N≤2000
对于 100\%100% 的数据,保证 1 le N le 10^51≤N≤105
对于所有的数据,保证 1 le M le 10^61≤M≤106 , 1 le H_i le 10^91≤Hi≤109 , 1 le K_i le 10^91≤Ki≤109 。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
(题外话:今天真是亢奋了一天ovo)
首先bfs一遍,筛出从1号点可以到达的点,并且用这些点建立一个新图
然后用最小生成时树跑一遍新图,记录路径长度....然后就没有然后了?
这是代码
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #include<queue> 7 #define N 1000010 8 #define LL long long 9 using namespace std; 10 int n,m; 11 LL sum,ans,fa[N],h[N]; 12 struct rockdu 13 { 14 LL u,v,w,nxt; 15 }e[N*2],d[N*2]; 16 int first[N],cnt,cnnt,head[N]; 17 bool vis[N]; 18 bool cmp(rockdu x,rockdu y) 19 {//终点的高度为第一关键字从大到小排序,边长为第二关键字从小到大排序 20 if(h[x.v]!=h[y.v]) return h[x.v]>h[y.v]; 21 return x.w<y.w; 22 } 23 void ade(LL u,LL v,LL w) 24 { 25 e[++cnt].nxt=first[u];first[u]=cnt; 26 e[cnt].u=u;e[cnt].v=v;e[cnt].w=w; 27 } 28 void adenew(LL u,LL v,LL w) 29 { 30 d[++cnnt].nxt=head[u];head[u]=cnnt; 31 d[cnnt].u=u;d[cnnt].v=v;d[cnnt].w=w; 32 } 33 void bfs()//buildnew 34 { 35 queue<LL>q; 36 q.push(1);vis[1]=1; 37 while(!q.empty()) 38 { 39 LL u=q.front(); q.pop(); 40 for(register LL i=first[u];i;i=e[i].nxt) 41 { 42 LL v=e[i].v; 43 adenew(u,v,e[i].w); 44 if(!vis[v]) 45 { 46 vis[v]=1; 47 sum++; 48 q.push(v); 49 } 50 } 51 } 52 } 53 //kruskal 54 inline long long la(long long x) 55 { 56 if(fa[x]!=x) fa[x]=la(fa[x]); 57 return fa[x]; 58 } 59 inline char nc(){ 60 static char buf[100000],*p1=buf,*p2=buf; 61 return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; 62 } 63 inline long long read(){ 64 char ch=nc();int sum=0; 65 while(!(ch>='0'&&ch<='9'))ch=nc(); 66 while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=nc(); 67 return sum; 68 } 69 int main() 70 { 71 n=read();m=read(); 72 for(register LL i=1;i<=n;i++) 73 { 74 h[i]=read(); 75 fa[i]=i; 76 } 77 for(register LL i=1;i<=m;i++) 78 { 79 LL a,b,c; 80 a=read();b=read();c=read(); 81 if(h[a]>=h[b]) ade(a,b,c); 82 if(h[a]<=h[b]) ade(b,a,c); 83 } 84 bfs(); 85 sort(d+1,d+cnnt+1,cmp); 86 for(register LL i=1;i<=cnnt;i++) 87 { 88 register LL x=la(d[i].u),y=la(d[i].v); 89 if(x!=y) 90 { 91 fa[x]=y; 92 ans+=d[i].w; 93 } 94 } 95 printf("%lld %lld",sum+1,ans); 96 return 0; 97 }
.