您的位置:首页 > 其它

hdu 5385 The path (贪心+最短路径树)

2015-08-16 15:38 323 查看



题目链接:点击打开链接

题意:一张图有N个顶点,给出一些有向边,问该如何给这些边赋值才能满足d(1) < d(2) < ….d(x) > d(x+1) > …d(n) 的条件且1为起点,d(x)表示1到x的最短距离. 赋值的范围在1~N。

解题思路:左边从2开始,右边从n开始,每次选与之前标记过的点相连的未标记过得点,该点的d[i]为该点加入的时间。最后输出时,判断该点是否在最短路上,不在的话,输出n,在的话输出d[v] - d[u]。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <queue>
#include <vector>
#include <set>
#include <map>
#include <climits>
using namespace std;

#define eps 1e-8;
const int INF=0x3f3f3f3f;
const int maxn=300000+10;
const int maxm=600000+10;
int d[maxn];
int f[maxn];
int n,m;

struct Edge
{
	int from,to;
	Edge(int from,int to):from(from),to(to){}
};
vector<Edge> edges;
vector<int> G[maxn];

void init()
{
	memset(f,0,sizeof(f));
	fill(d,d+n+1,INF);
	edges.clear();
	for(int i=1;i<=n;i++)G[i].clear();
	d[1]=0;
	d[2]=1;
	d
=1;
	f[1]=-1;
}

void addEdge(int from,int to)		//邻接表实现
{
	edges.push_back(Edge(from,to));
	int x=edges.size();
	G[from].push_back(x-1);
}

void mark(int x)
{
	for(int i=0;i<G[x].size();i++)
	{
		int v=edges[G[x][i]].to;
		if(!f[v])f[v]=x;
	}
}

int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d",&n,&m);
		init();
		for(int i=0;i<m;i++)
		{
			int u,v;
			scanf("%d%d",&u,&v);
			addEdge(u,v);
		}
		int l=1,r=n;
		int dis=1;
		while(l<=r)
		{
			if(f[l])
			{
				mark(l);
				d[l]=dis++;
				l++;
			}
			if(f[r])
			{
				mark(r);
				d[r]=dis++;
				r--;
			}
		}
		for(int i=0;i<m;i++)
		{
			int u=edges[i].from;
			int v=edges[i].to;
			if(f[v]!=u)printf("%d\n",n);
			else printf("%d\n",d[v]-d[u]);
		}
	}
	return 0;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: