【牛客 - 370H】Rinne Loves Dynamic Graph(分层图最短路)

题干:

链接:https://ac.nowcoder.com/acm/contest/370/H
来源:牛客网
 

Rinne 学到了一个新的奇妙的东西叫做动态图,这里的动态图的定义是边权可以随着操作而变动的图。
当我们在这个图上经过一条边的时候,这个图上所有边的边权都会发生变动。

定义变动函数 f(x)=11−xf(x)=11−x,表示我们在图上走过一条边后,图的边权变动情况。

这里指的“图的变动”的意思是将每条边的边权代入上函数,得到的值即为该次变动后的边权。

现在 Rinne 想要知道,在这个变动的图上从 1 到 n 的最短路径。
因为 Rinne 不喜欢负数,所以她只需要你输出经过的边权权值绝对值之和最小的那个值就可以了。
输出答案保留三位小数。

输入描述:

第一行两个正整数 N,M,表示这个动态图的点数和边数。
接下来 M 行,每行三个正整数 u,v,w,表示存在一条连接点 u,v 的无向边,且初始权值为 w。

输出描述:

如果能到达的话,输出边权绝对值之和最小的答案,保留三位小数。
否则请输出 -1。

示例1

输入

复制

3 3
1 2 2
2 3 2
3 1 3

输出

复制

3.000

说明

走 1→2→31→2→3,总花费 2+|11−2|=32+|11−2|=3

备注:

n≤100000,m≤300000,2≤x≤1000

解题报告:

   mmp的这题卡常卡我半天,,不能用spfa不能用vector、、、还有就是注意数组大小,边数要开6*MAXM,,因为是双向边、、不然就会TLE。

   读题发现这个函数是个迭代函数。

  发现这一点之后这题就解决一大半了,建三层的图,每一层只能连向更高层。跑Dijkstra就行了。最后在三个答案中取最小。当然这题也可以用dp的思想去做。

  注意这题有个坑,就是你加边的时候不能直接更新了w,就将w取绝对值了,而是应该,传参的时候传进去绝对值,但是w还是保持本身的值。(这个坑不注意还真发现不了、、、就看你写的姿势如何了)

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define pm make_pair
using namespace std;
const int MAX = 2e5 + 5;
typedef pair<int,double> PID;
typedef pair<double,int> PDI;
const double INF = 99999999999;
int n,m;
//vector<PID > vv[3*MAX];
double dis[MAX*3];
bool vis[MAX*3];
int head[MAX*3];
struct Node {int to,ne;double w;
} e[MAX*15];
int tot;
void add(int u,int v,double w) {e[++tot].to = v;e[tot].w = w;e[tot].ne = head[u];head[u] = tot;
}
void Dijkstra() {for(int i = 1; i<=3*n; i++) dis[i] = INF;dis[1] = 0;priority_queue<PDI> pq;pq.push(pm(0,1));while(!pq.empty()) {PDI cur = pq.top();pq.pop();if(vis[cur.se]) continue;vis[cur.se] = 1;for(int i = head[cur.se]; i!=-1; i=e[i].ne) {int v = e[i].to;if(dis[cur.se] + e[i].w < dis[v]) {dis[v] = dis[cur.se] + e[i].w;pq.push(pm(-dis[v],v));}}}
}
int main()
{memset(head,-1,sizeof head);cin>>n>>m;int u,v;double w;for(int i = 1; i<=m; i++) {scanf("%d%d%lf",&u,&v,&w);//w = fabs(w);add(u,v+n,fabs(w));add(v,u+n,fabs(w));w = (1.0/(1-w));add(u+n,v+2*n,fabs(w));add(v+n,u+2*n,fabs(w));w = (1.0/(1-w));add(u+2*n,v,fabs(w));add(v+2*n,u,fabs(w));}Dijkstra();double ans = INF;for(int i = 0; i<=2; i++) {ans = min(ans,dis[n+i*n]);}if(ans > 9999999999) printf("-1\n");else printf("%.3lf\n",ans);return 0 ;}

AC代码2:(dp思路)

#include<bits/stdc++.h>
using namespace std;
const int MOD=1e9+7;
const int MAX=5e5+10;
typedef long long ll;
struct lenka
{int x,y;double cost;bool operator<(const lenka&q)const{return q.cost<cost;}
};
vector<pair<int,int> >e[MAX];
priority_queue<lenka>p;
double d[MAX][3];
double f(int x,int tp)
{if(tp==0)return x*1.0;if(tp==1)return 1/(x-1.0);return 1-1.0/x;
}
void bfs()
{p.push((lenka){1,0,0.0});d[1][0]=0;while(!p.empty()){lenka now=p.top();p.pop();if(fabs(d[now.x][now.y]-now.cost)>1e-8)continue;for(int i=0;i<e[now.x].size();i++){pair<int,int>nex=e[now.x][i];if(d[nex.first][(now.y+1)%3]>now.cost+f(nex.second,now.y)){d[nex.first][(now.y+1)%3]=now.cost+f(nex.second,now.y);p.push((lenka){nex.first,(now.y+1)%3,d[nex.first][(now.y+1)%3]});}}}
}
int main()
{int n,m;cin>>n>>m;for(int i=1;i<=n;i++)d[i][0]=d[i][1]=d[i][2]=6e18;while(m--){int x,y,z;scanf("%d%d%d",&x,&y,&z);e[x].push_back({y,z});e[y].push_back({x,z});}bfs();double ans=*min_element(d[n],d[n]+3);if(ans>5e18)puts("-1");else printf("%.3lf\n",ans);return 0;
}

再来一个:

#pragma comment(linker, "/STACK:102400000,102400000")//防止栈溢出!!!
#include<cstdio>
#include<iostream>
#include<stdlib.h>
#include<malloc.h>
#include<cstring>
#include<algorithm>
#include<math.h>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <stack>
#include<time.h>
#include<ctype.h>
#define REP(I,N) for (I=0;I<N;I++)
#define rREP(I,N) for (I=N-1;I>=0;I--)
#define rep(I,S,N) for (I=S;I<N;I++)
#define rrep(I,S,N) for (I=N-1;I>=S;I--)
#define For(i,x,y)  for(long long i=(long long)(x);i<(long long)(y);++i)
#define rFOR(I,S,N) for(long long I=N;I>=S;I--)
#define SWAP(x,y) {(x) = (x)^(y); (y)=(x)^(y); (x)=(x)^(y);}
#define D(x) cerr<<#x<<" = "<<x<<endl
#define ms(a,b) memset(a,b,sizeof(a))
#define lowbit(x) ((x)&(-x)) 
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double eps=1e-6;
const int MOD = 1e9+6 ;
const int mod = 1e9+7;
const int INF = 0x3f3f3f3f;
const int MAXN =100010;const double pi=acos(-1.0);
template<class T>inline void rd(T &x){int Finish_read=0;x=0;int f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();x*=f;Finish_read=1;}
template<class T> inline T Maxx(const T&a,const T&b){return a < b?b:a;}
template<class T> inline T Minn(const T&a,const T&b){return a < b?a:b;}
template<class T> inline T gcd(T a,T b) {return b?gcd(b,a%b):a;}
template<class T> inline T lcm(T x,T y) {return x/gcd(x,y)*y;}
struct node{  int to;int cnt;ll w; 
//  bool operator <(const node &t)const{
//      if(le-ri==t.le-t.ri)
//          return le<t.le;
//      else
//          return le-ri<t.le-t.ri;
//  }
};   
struct qnode{int v;//节点idint k;double c;//源节点到v的暂且最短距离  bool operator <(const qnode &r)const{return c>r.c;}
};
struct Edge
{int    to , next;double w ;
} e[600010];//bool vis[MAXN][3];
double dist[MAXN][3];
//点的编号从 1 开始int  cnt,p[ MAXN ] ;
void Add_Edge(const int x ,const int y ,const int w ){e[ ++cnt ] . to = y ;e[ cnt ] . next = p[ x ];e[ cnt ] . w = w ;p[ x ] = cnt ;return ;
}
inline double f( double X , int N ) {switch( N ) {case 1 : {return X ;break ;}case 2 : {return fabs( 1 / ( 1 - X ) ) ;break ;}case 0 : {return fabs( ( X - 1 ) / X ) ;break ;}}return 0.0 ;
}
double dinf;
void Dijkstra(int start ){//memset(vis,false,sizeof(vis));priority_queue<qnode>que;memset(dist,127,sizeof(dist));while(!que.empty())que.pop();dinf=dist[0][0];dist[start][0]=0;que.push((qnode){start,0,0});while( que.size()){qnode tmp=que.top();que.pop();int u=tmp.v;if(fabs(tmp.c-dist[u][tmp.k])>1e-7)continue;//如果更新过此状态,就不再放入队列//  vis[u]=true;int nk=(tmp.k+1)%3;for( int i=p[u] ; i ; i = e[ i ].next ){int v=e[ i ].to;double cost=tmp.c+ f(e[ i ].w,nk) ;if( dist[v][nk]> cost){dist[v][nk]=cost;que.push( (qnode){v,nk,cost});}}}
}
int main(int argc, char** argv)  
{     //freopen("E://dev//input.in","r",stdin); int  n,m;scanf("%d%d",&n,&m );int u,v,w ;for(int i=0;i<m;i++){rd(u),rd(v),rd(w);Add_Edge(u,v,w*1.0);Add_Edge(v,u,w*1.0);  } Dijkstra(1) ;double ans=Minn(dist[n][0],Minn(dist[n][1],dist[n][2]));if(fabs(ans-dinf)>1e-7)//与初始化的浮点型INF比较大小printf("%.3lf\n",ans);elseputs( "-1" ) ;return 0; 
}  

或者把这里改了:

inline double f( double X , int N ) {switch( N ) {case 0 : {return X ;break ;}case 1 : {return fabs( 1 / ( 1 - X ) ) ;break ;}case 2 : {return fabs( ( X - 1 ) / X ) ;break ;}}return 0.0 ;
}
double dinf;
void Dijkstra(int start ){//memset(vis,false,sizeof(vis));priority_queue<qnode>que;memset(dist,127,sizeof(dist));while(!que.empty())que.pop();dinf=dist[0][0];dist[start][2]=0;que.push((qnode){start,2,0});

之所以最后三个的代码(换句话说是倒数第三个   和   后两个)之所以有区别(指的是f函数的区别),就是因为传入的参数

if(d[nex.first][(now.y+1)%3]>now.cost+f(nex.second,now.y))  倒数第三个  的代码是now.y+1%3  但是算f函数是now.y。。。

倒数第二个,算f函数也是传的nk(相当于是now.y+1),所以函数体内当然不一样咯。。。

所以其实实质都是一样的,,只不过实现方式不一样而已、、

还有就是while里面的 if(fabs(tmp.c-dist[u][tmp.k])>1e-7)continue;其实可以不用写、、、只是会稍微慢一点点。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/440791.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

中位数及带权中位数问题(转)

先从一到简单的题看起&#xff1a; 士兵站队问题 在一个划分成网格的操场上&#xff0c;n个士兵散乱地站在网格点上。网格点由整数坐标(x,y)表示。士兵们可以沿网格边上、下、左、右移动一步&#xff0c;但在同一时刻任一网格点上只能有一名士兵。按照军官的命令&#xff0c;…

java编写学籍管理系统_java学籍管理系统源代码.doc

java学籍管理系统源代码package zuoye;//主类import java.awt.*;import java.awt.event.*;import javax.swing.*;import java.io.*;import java.util.Hashtable;public class ManagerWindow extends JFrame implements ActionListener{InputStudent 基本信息录入null;ModifySit…

*【SGU - 114】Telecasting station (带权中位数 或 三分)

题干&#xff1a; Every city in Berland is situated on Ox axis. The government of the country decided to build new telecasting station. After many experiments Berland scientists came to a conclusion that in any city citizens displeasure is equal to product…

java的et5_Javascript与java相同的3des加密(使用etdesede/CBC/PKCS5Padding )

在某个项目中&#xff0c;需要开发一个与native相对应的web前端app&#xff0c;后台用的是java restful接口&#xff0c;请求数据时需要用的3des加密。如果想要请求接口&#xff0c;则需要javascript的加密与java相同&#xff0c;于是在baidu与google进行了大量搜索&#xff0c…

*【HDU - 4272 】LianLianKan (dfs 或 状压dp,贪心不行)

题干&#xff1a; I like playing game with my friend, although sometimes looks pretty naive. Today I invent a new game called LianLianKan. The game is about playing on a number stack. Now we have a number stack, and we should link and pop the same element…

java中的values函数_巧用valueat函数(快逸免费版)

在制作报表时&#xff0c;经常会遇到将数据库里一列数据按照条件取值后&#xff0c;分为多列显示的需求&#xff0c;例如&#xff1a;数据库中有一列名为type的数据&#xff0c;在报表中&#xff0c;第一列选择type为1的数据&#xff0c;第二列选择type为2的数据。由于受到扩展…

Java设计流程执行器_Java进阶面试精选系列:SpringMVC+SpringBoot+Hibernate+Mybatis+设计模式...

小编精心收集&#xff1a;为金三银四准备&#xff0c;以下面试题先过一遍&#xff0c;为即将到了的面试做好准备&#xff0c;也过一遍基础知识点。一、Spring/Spring MVC1.为什么要使用 spring&#xff1f;2.解释一下什么是 aop&#xff1f;3.解释一下什么是 ioc&#xff1f;3.…

【CCFCSP - 201403-4】无线网络(分层图最短路)

题干&#xff1a; 试题编号&#xff1a;201403-4试题名称&#xff1a;无线网络时间限制&#xff1a;1.0s内存限制&#xff1a;256.0MB问题描述&#xff1a; 问题描述   目前在一个很大的平面房间里有 n 个无线路由器,每个无线路由器都固定在某个点上。任何两个无线路由器只要…

【牛客 - 370E】Rinne Loves Gift(Bellman_Ford判负环,二分,分数规划)

题干&#xff1a; 链接&#xff1a;https://ac.nowcoder.com/acm/contest/370/E 来源&#xff1a;牛客网 Rinne 喜欢礼物&#xff0c;也喜欢送礼物 圣诞节快到了&#xff0c;Rinne 要去给给住在城市里的人送礼物 城市的交通可以抽象成一个 n 个点 m 条边的有向图 每条边上有…

【POJ - 2976】【ZOJ - 3068】【SCU - 2992】Dropping tests (01分数规划)

题干&#xff1a; In a certain course, you take n tests. If you get ai out of bi questions correct on test i, your cumulative average is defined to be . Given your test scores and a positive integer k, determine how high you can make your cumulative aver…

重写过的url 怎么获取当前页面url java_网站URL重写(Java UrlRewrite 的使用)

现在大部分的网站和商城都会使用到URL重写&#xff0c;接触到这个&#xff0c;也是因为正在做的电子商务商城。URL重写&#xff0c;是将原有的URL采用另一种规则来显示&#xff0c;使得用户方便访问同时也屏蔽一些信息。在此说下它的好处&#xff0c;在开发过程中&#xff0c;经…

【51nod - 1050】循环数组最大子段和(dp)

题干&#xff1a; N个整数组成的循环序列a[1],a[2],a[3],…,a[n]&#xff0c;求该序列如a[i]a[i1]…a[j]的连续的子段和的最大值&#xff08;循环序列是指n个数围成一个圈&#xff0c;因此需要考虑a[n-1],a[n],a[1],a[2]这样的序列&#xff09;。当所给的整数均为负数时和为0。…

Java行业情景分析_Java 设计模式情景分析——单例模式

单例模式可以说是应用最广的模式之一&#xff0c;在应用单例模式时&#xff0c;单例对象的类必须保证只有一个实例存在&#xff0c;而且可以自行实例化并向整个系统提供这个实例。一般在不能自由构造对象的情况下&#xff0c;就会使用单例设计模式&#xff0c;例如创建一个对象…

笔试题 - 汽车加油问题

题干&#xff1a; 第一行输入n&#xff0c;k&#xff0c;代表共有k个加油站&#xff0c;加满油后可以跑n公里。 第二行k1个数&#xff0c;其中前k个数代表加油站的位置&#xff0c;第k1个数代表终点的位置。 一辆车从坐标零点加满油后出发&#xff0c;问最少加几次油&#xff0…

php实现播放直播_PHP直播技术分享(一:实现直播)

推流服务器采用的是自搭的推流服务器 , 自己玩玩 做外包项目还是去搞七牛云/阿里这样的服务器吧,开始bb-----1:技术栈image.jpeg2:开发中业务(1)主播申请时创建个秘钥 , 这个秘钥随时字符串即可到时候根据字符串找到拉流的直播位置存数据库包括推流地址image.png3:配置nginx-rt…

笔试题 - 阶乘问题

题干&#xff1a; 【题意】 给你一个数组n&#xff08;1<n<1e5&#xff09; 让你输出有多少数的阶乘后恰好有n个0&#xff0c;并依次输出。 【类型】 二分or暴力 【分析】 肯定满足&#xff0c;数字越大&#xff0c;其后的0的个数也就越多。 于是我们可以二分出最小的l&…

php获取location,php获取header[‘location’]信息常见问题

15/01/31本文关键字: 302, header, location//初始化url信息$host “#8221;;$url$host.”l/rzTf7ap2viw/&iid222004556&resourceId0_04_05_99/v.swf”;//按照字段获取header响应信息$headers get_headers($url, TRUE);//获取这个土豆的302跳转地址$u302 $headers[“Lo…

【计蒜客 - 蓝桥训练】蒜厂年会(单调队列优化dp,循环数列的最大子段和)

题干&#xff1a; 在蒜厂年会上有一个抽奖&#xff0c;在一个环形的桌子上&#xff0c;有 nn 个纸团&#xff0c;每个纸团上写一个数字&#xff0c;表示你可以获得多少蒜币。但是这个游戏比较坑&#xff0c;里面竟然有负数&#xff0c;表示你要支付多少蒜币。因为这些数字都是…

php对联广告,html左右对联代码 cms网站对联广告html代码

实现网页左右两侧居中的对联广告代码你只记得自己有好多朋友却从没想过小编只有你一人。无标题文档 #left{ width:200px;height:450px; position:absolute; left:0px; background:red; border:1px #000 solid} #right{width:200px;height:450px; position:absolute; right:0px;…

php 分页 url重写 分页问题,解决千古难题,wordpress分页URL问题,wordpress给分页加链接...

原本的wordpress文章如果分页会成如下的结构&#xff1a;http://www.xyqzmt.cn/1.html/2通常固定链接都是这样的结构&#xff0c;设为/%postname%.html或者/%post_id%.html 以前我一直无法解决如上的问题&#xff0c;最后放弃挣扎&#xff0c;如果遇到很长的文章全都放在一个页…