题目链接:http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1280
这道题一开始纯用最短路re了,离散化后又T了,最后优化才过
代码如下:
#include <map>
#include <string>
#include <vector>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <cstring>
#include <iostream>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=20005;
struct node
{
int next,to,w;
} e[maxn*3];
struct point
{
int p,num;
} a[maxn];
struct dode
{
int x,d;
bool operator<(const dode &t) const
{
return d>t.d;
}
};
int dis[maxn],vis[maxn];
int head[maxn],cnt;
void add(int u,int v,int w)
{
e[cnt].next=head[u];
e[cnt].w=w;
e[cnt].to=v;
head[u]=cnt++;
}
int cmp(struct point x1,struct point y1)
{
return x1.p<y1.p;
}
void spfa(int x,int sum,int en)
{
memset(vis,0,sizeof(vis));
for(int i=0; i<sum; i++)
{
dis[i]=INF;
}
dis[x]=0;
priority_queue<dode> q;
while(!q.empty())
q.pop();
q.push( {x,dis[x]});
while(!q.empty())
{
int u=q.top().x;
q.pop();
if(u==en)
return;
if(vis[u])
continue;
vis[u]=1;
for(int i=head[u]; i!=-1; i=e[i].next)
{
int v=e[i].to;
int w=e[i].w;
if(!vis[v]&&dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
q.push( {v,dis[v]});
}
}
}
}
int main()
{
int t;
scanf("%d",&t);
int k=0;
while(t--)
{
k++;
int n,m;
scanf("%d%d",&n,&m);
cnt=0;
memset(head,-1,sizeof(head));
for(int i=1; i<=m; i++)
{
int u,v;
scanf("%d%d",&u,&v);
add(i*2-1,i*2,0);
add(i*2,i*2-1,0);
a[i*2-1].p=u;
a[i*2-1].num=i*2-1;
a[i*2].p=v;
a[i*2].num=i*2;
}
sort(a+1,a+2*m+1,cmp);//此处为了之后存入各点的距离排序
add(0,2*m+1,n-1);
if(m>0)
{
add(0,a[1].num,a[1].p-1);
add(a[2*m].num,2*m+1,n-a[2*m].p);
}
for(int i=1; i<2*m; i++)
{
add(a[i].num,a[i+1].num,a[i+1].p-a[i].p);
add(a[i+1].num,a[i].num,a[i+1].p-a[i].p);
}
spfa(0,2*m+2,2*m+1);
printf("Case #%d: %d\n",k,dis[2*m+1]);
}
return 0;
}