NIKKEI Programming Contest 2019-2 D 部分分题解

请注意本文章所描写的算法只可以获得前 14 个测试点(含三个样例)的部分分,但是没有出现 WA 的情况。

推荐阅读

题面

给出 \(m\) 个线段,每次可以从线段上任意一点以代价 \(c_i\) 走到线段上另一点,每条线段只能使用一次,求从 \(1\) 位置走到 \(n\) 位置的最小代价。

部分分题解

观察样例可以发现,在线段上走的目的其实是走到下一个线段/终点上,因此当前点转化成了当前线段的移动,一定程度上减小了时间复杂度,但是由于线段移动可行性的判断是 \(O(m^2)\) 的,而移动方案数也可以被卡到 \(O(m^2)\)(起点 \(s_i=s_{i-1}\),终点 \(t_i=t_{i-1}+1\)),因此这个算法效率也并不是太高,但是此处的转化思想还是挺有意义的。

代码

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include<climits>
const int MAXN=1e5+5;
struct Edge{int u,v,next;long long w;};
struct Point
{
	int v;long long w;
	bool operator < (const Point &b) const
	{
		return w==b.w?v<b.v:w>b.w;
	}
};
std::priority_queue<Point>que;
long long sample;int n,m,head[MAXN],cnt,u[MAXN],v[MAXN];bool vis[MAXN];long long dis[MAXN],w[MAXN];Edge edge[MAXN*3];
void AddEdge(int u,int v,long long w)
{
	//printf("%d %d %lld\n",u,v,w);
	edge[++cnt].u=u;edge[cnt].v=v;edge[cnt].w=w;
	edge[cnt].next=head[u];head[u]=cnt;
}
void Dijkstra()
{
	Point tmp,temp;
	memset(dis,0x3f3f3f,sizeof(dis));
	temp.v=0;temp.w=0;sample=dis[0];dis[0]=0;
	que.push(temp);
	while(!que.empty())
	{
		temp=que.top();que.pop();
		if(vis[temp.v]) continue;
		//printf("%d\n",temp.v);
		vis[temp.v]=1;
		for(int i=head[temp.v];i;i=edge[i].next)
		{
			//printf("%d*\n",edge[i].v);
			if(dis[edge[i].v]>dis[temp.v]+edge[i].w)
			{
				//printf("%d ADD\n",edge[i].v);
				dis[edge[i].v]=dis[temp.v]+edge[i].w;
				tmp.v=edge[i].v;
				tmp.w=dis[edge[i].v];
				que.push(tmp);
			}
		}
	}
}
bool cover(int s1,int t1,int s2,int t2)
{
	if(t2<=t1) return 0;
	return (s2>=s1&&t2<=t1)||(((s2<=s1&&t2>=s1)||(s2<=t1&&t2>=t1)));
}
int main()
{
	scanf("%d %d",&n,&m);
 
	for(int i=1;i<=m;i++)
	{
		scanf("%d %d %lld",&u[i],&v[i],&w[i]);
		if(u[i]==1) AddEdge(0,i,w[i]);
	}
	for(int i=1;i<=m;i++)
		for(int j=1;j<=m;j++)
			if(i!=j&&cover(u[i],v[i],u[j],v[j])) AddEdge(i,j,w[j]);
	Dijkstra();
	long long ans=LLONG_MAX;bool flag=0;
	for(int j=1;j<=m;j++)
		if(v[j]==n){ans=std::min(ans,dis[j]);}
	printf("%lld",(ans==LLONG_MAX||ans==sample)?-1:ans);
	return 0;
}
posted @ 2019-11-09 22:07  酷暑一夏1  阅读(235)  评论(0编辑  收藏  举报