HDU - 5636 Shortest Path (判断最短路)

HDU - 5636
Shortest Path
Time Limit: 2000MS   Memory Limit: 131072KB   64bit IO Format: %I64d & %I64u

Submit Status

Description

There is a path graph   with   vertices. Vertices are numbered from   to   and there is an edge with unit length between   and    . To make the graph more interesting, someone adds three more edges to the graph. The length of each new edge is 

You are given the graph and several queries about the shortest path between some pairs of vertices.
 

Input

There are multiple test cases. The first line of input contains an integer  , indicating the number of test cases. For each test case: 

The first line contains two integer   and     -- the number of vertices and the number of queries. The next line contains 6 integers    , separated by a space, denoting the new added three edges are 

In the next   lines, each contains two integers   and    , denoting a query. 

The sum of values of   in all test cases doesn't exceed  .
 

Output

For each test cases, output an integer  , where   is the answer for  -th query.
 

Sample Input

         
         
         
         
1 10 2 2 4 5 7 8 10 1 5 3 1
 

Sample Output

         
         
         
         
7
本来想着用模拟来将,所有的情况模拟,但发现当包含三条边时,情况太多了,模拟了一个小时,直接就崩溃了,还是另寻他路吧!!!
看了大神的博客,他是用DFS写的,50行就解决了,这对于我这个dfs渣渣来说实在是太难了。。
DFS的思路是:
在每次查询时,可以分四种情况
1、一条边都不加;
2、只加入一条边;
3、加入两条边;
4、三条边都加入;
一直模拟到3条边都加入,找到最小的距离就行了。
#include<stdio.h>  
#include<string.h>  
#include<math.h>  
#include<algorithm>  
#include<iostream>  
#include<queue>  
#define INF 0x3f3f3f3f  
#define IN __int64  
#define ull unsigned long long  
#define ll long long  
#define N 100010  
#define M 1000000007  
using namespace std;  
ll ans,sum;
int vis[5];
int n,m,a[5][2],x,y;
void dfs(int k,int now,int dis)
{
	if(dis+abs(now-y)<ans)
		ans=dis+abs(now-y);
	if(k>3)
		return ;
	for(int i=0;i<3;i++)
	{
		if(!vis[i])
		{
			vis[i]=1;
			dfs(k+1,a[i][0],dis+abs(now-a[i][1])+1);
			dfs(k+1,a[i][1],dis+abs(now-a[i][0])+1);
			vis[i]=0;
		}
	}
}
int main()
{
	int t,i;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&n,&m);
		for(i=0;i<3;i++)
			scanf("%d%d",&a[i][0],&a[i][1]);
		memset(vis,0,sizeof(vis));
		sum=0;
		for(i=1;i<=m;i++)
		{
			scanf("%d%d",&x,&y);
			ans=abs(x-y);
			dfs(1,x,0);
			sum=(sum+i*ans)%M;
		}
		printf("%I64d\n",sum);
	}
	return 0;
}

 
//WA了考虑的太少。。
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<iostream>
#include<queue>
#define INF 0x3f3f3f3f
#define IN __int64
#define ull unsigned long long
#define ll long long
#define N 100010
#define M 1000000007
using namespace std;
struct zz
{
	int x;
	int y;
	int l;
}p[N];
int cmp(zz a ,zz b)
{
	if(a.x==b.x)
		return a.y<b.y;
	return a.x<b.x;
}
int main()
{
	int t;
	int n,m;
	int i,j,k;
	int x,y,s,e;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&n,&m);
		for(i=0;i<3;i++)
		{
			scanf("%d%d",&p[i].x,&p[i].y);
			if(p[i].x>p[i].y)
			{
				int tt=p[i].x;p[i].x=p[i].y;p[i].y=tt;
			}
			p[i].l=p[i].y-p[i].x;
		}
		sort(p,p+3,cmp);
		ll sum=0;
		for(i=1;i<=m;i++)
		{			
			scanf("%d%d",&s,&e);
			int ss=-1,ee=-1;
			int l=e-s;
			if(s>e)
			{
				int tt=s;s=e;e=tt;
			}			
			for(j=0;j<3;j++)
			{
				if(s<=p[j].x)
				{
					ss=j;
					break;
				}
			}
			for(j=2;j>=0;j--)
			{
				if(e>=p[j].y)
				{
					ee=j;
					break;
				}
			}
			int kl=0;
			if(ss==ee)
				sum=(sum+(l-p[ss].l+1)*i)%M;
			else if(ss<ee)
			{
				for(j=ss;j<=ee;j++)
					kl+=p[j].l;
				sum=(sum+(l-kl+1)*i)%M;
			}
			else
				sum=(sum+l*i)%M;
		}
		printf("%lld\n",sum);
	}
	return 0;
}
//开始时用的是SPFA写,超时了,
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<iostream>
#include<queue>
#define INF 0x3f3f3f3f
#define IN __int64
#define ull unsigned long long
#define ll long long
#define N 100010
#define M 1000000007
using namespace std;
struct zz
{
	int from;
	int to;
	int val;
	int next;
}edge[N];
int head[N],edgenum;
int n,m;
int dis[N];
int vis[N];
void add(int u,int v,int w)
{
	zz E={u,v,w,head[u]};
	edge[edgenum]=E;
	head[u]=edgenum++;
}
void SPFA(int x)
{
	queue<int>q;
	memset(vis,0,sizeof(vis));
	memset(dis,INF,sizeof(dis));
	q.push(x);
	dis[x]=0;
	vis[x]=1;
	while(!q.empty())
	{
		int u=q.front();
		q.pop();
		vis[u]=0;
		for(int i=head[u];i!=-1;i=edge[i].next)
		{
			int v=edge[i].to;
			if(dis[v]>dis[u]+edge[i].val)
			{
				dis[v]=dis[u]+edge[i].val;
				if(!vis[v])
				{
					vis[v]=1;
					q.push(v);
				}
			}
		}
	}
}
int main()
{
	int t;
	int i,j,k;
	int x,y,s,e;
	scanf("%d",&t);
	while(t--)
	{
		memset(head,-1,sizeof(head));
		edgenum=0;
		scanf("%d%d",&n,&m);
		for(i=1;i<n-1;i++)
		{
			add(i,i+1,1);
			add(i+1,i,1);
		}
		for(i=0;i<3;i++)
		{
			scanf("%d%d",&x,&y);
			add(x,y,1);
			add(y,x,1);
		}
		SPFA(1);
		int sum=0;
		for(i=1;i<=m;i++)
		{
			scanf("%d%d",&s,&e);
			
//			printf("%d\n",dis[e]);
			sum=(sum+i*(abs)(dis[e]-dis[s]))%M;
		}
		printf("%d\n",sum);
	}
	return 0;
}



你可能感兴趣的:(HDU - 5636 Shortest Path (判断最短路))