Silver Cow Party POJ-3268+ Converting Multi-Source Shortest Path to Single-Source Shortest Path in Linear Space

			        		****First of all, thanks for pxgg's support and help*****

Title Link

* Topic to the point, N cows, going X (1<=X<=N) along a one-way road from their respective locations (their number 1,2,--N),
* After the party, N cows follow a one-way road back to their original place.It takes the least time to ask back and forth.
Data range: 1 < N < 1000, 1 < M < 100,000, Ti, 1 < Ti < 100; Number of points, number of edges, time required for a road.
Time requirement: 2000ms;
The algorithm used is: Floyd,O(N^3) timeout; bellman, O (N*M), timeout; **dijkstra**, before optimization, O (N^2), runnable, ** after optimization**, O((N+M) log2(N)), strong.
Title requirements: (1) find out the distance from n cows to a place sum1,
		 (2) Calculate the distance of N cows from one place to n places sum2.
		 (3) output sum1+sum2;
The second easy problem to solve is to run while dijkstra calculates the sum of the minimum distances from X to n.
Question (1) is about the distance from point n to point X, so we think:
There are 4 points, 1, 2, 3, 4, to go to point 2, the shortest known route is as follows:
These paths are one-way, and if we find the shortest distance from each point to 2, the maximum number of runs, the dijkstra complexity will not work, it will certainly exceed.
The length of the path is fixed, so we think it's time to let the cow walk back to point 2.These distances are sum1;
1-->3-->2;
2;
3-->4-->2;
4-->1-->2;

These paths are:
2-->3-->1;
2;
2-->4-->3;
2-->1-->4;

Our problem becomes finding the distance from point 2 to each vertex.
*** But we need to reverse all the edges, because if we don't, what do we ask? Ha Ha Ha Ha Ha Ha Ha Ha.***
//I used vector s to save pictures when I was doing the questions and adjacency tables when I was writing a blog. The result was changed for more than half an hour. I'm very dishy.
//Handwritten adjacency tables, unlike vectors that implement adjacency tables, use of vectors can add some extra time.
//32 ms with vector s and 16 ms with handwritten adjacency tables;
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int num_e=100000+10;
const int num_p=1010;
const int inf=0x3f3f3f3f;
struct node 
{
	int v,w,next;
	node(){};
	node(int a,int b)
	{
		v=a;w=b;
	}
	
	bool operator < (const node & s) const
	{
		return w > s.w;
	}
}edge[num_e];
int head[num_p];
int from[num_e],to[num_e],worth[num_e];
int date[2][num_e];
int n,m,x,cnt;
void int_i(void)
{
	cnt=0;
	for(int j=1;j<=n;j++)
	head[j]=0;
	return ;
}
void addedge(int a,int b,int c)
{
	edge[++cnt].v=b;
	edge[cnt].w=c;
	edge[cnt].next=head[a];
	head[a]=cnt;
	return ;
}
void dijkstra(int g)
{
	int dis[n+1];
	int book[n+1];
	for(int i=1;i<=n;i++)
	{
		dis[i]=inf;
		book[i]=0;
	}
	dis[x]=0;
	
	priority_queue<node>q;//Be sure to use the priority queue, because it's been adjusted here for half an hour, thank you pxgg.
	q.push(node(x,0));
	
	while(!q.empty())
	{
		node x=q.top();q.pop();
		
		if(book[x.v])
		continue;
		book[x.v]=1;
		
		for(int i=head[x.v];i;i=edge[i].next)
		{
			int y=edge[i].v;
			if(book[y]) continue;
			
			if(dis[y] > x.w + edge[i].w)
			{
				dis[y]=x.w + edge[i].w;
				q.push(node(y,dis[y]));
			}
		}
	}
	
	for(int i=1;i<=n;i++)
	{
		date[g][i]=dis[i];
	}
	return ;
}
int main()
{
	scanf("%d%d%d",&n,&m,&x);
	int_i();
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&from[i],&to[i],&worth[i]);
		addedge(from[i],to[i],worth[i]);
	}
	
	dijkstra(0);
	
	int_i();
	//Store the edge upside down and run again
	for(int i=1;i<=m;i++)
	{
		addedge(to[i],from[i],worth[i]);
	}
	dijkstra(1);
	
	int maxm=0;
	for(int i=1;i<=n;i++)
	maxm=max(maxm,date[0][i]+date[1][i]);
	printf("%d\n",maxm);
	return 0;
} 

//vector version, running 32 ms
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int inf=0x3f3f3f3f;
const int num=1010;
struct edge
{
	int u,v,w;
	edge(int a,int b,int c)
	{
		u=a;v=b;w=c;	
	}	
};
vector<edge>e[num];
int from[num],to[num],time[num];//´æ´¢Êý¾Ý 
int date[2][num];
struct point
{
	int id,n_dis;
	point(int a,int b)
	{
		id=a;n_dis=b;	
	}	
	bool operator < (const point &a) const
	{
		return n_dis > a.n_dis; 
	}
};
void dijkstra(int g,int x,int n)
{
	int dis[num];
	bool book[num];
	
	for(int i=1;i<=n;i++) 
	{
		dis[i]=inf;
		book[i]=false;
	}
	dis[x]=0;
	
	priority_queue<point>q;
	q.push(point(x,0));
	
	while(!q.empty())
	{
		point x=q.top();
		q.pop();
		
		if(book[x.id])
		continue;
		book[x.id]=true;
		
		for(int i=0;i<e[x.id].size();i++)
		{
			edge y=e[x.id][i];
			
			if(book[y.v])
			continue;
			
			if(dis[y.v] > x.n_dis + y.w)
			{
				dis[y.v] = x.n_dis + y.w;
				q.push(point(y.v,dis[y.v]));
			}
		}
	}
	
	for(int i=1;i<=n;i++)
	date[g][i]=dis[i];
	
	return ;
}
int main()
{
	int x,n,m;
	int u,v,w;
	int sum=0;

	scanf("%d%d%d",&n,&m,&x);
		
	for(int i=1;i<=n;i++)
	{
		e[i].clear();
	}
		
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&from[i],&to[i],&time[i]);
		e[to[i]].push_back(edge(to[i],from[i],time[i]));
	}
	dijkstra(0,x,n);
	
	for(int i=1;i<=n;i++)
	{
		e[i].clear();
	}
	
	for(int i=1;i<=m;i++)
	{
		e[from[i]].push_back(edge(from[i],to[i],time[i]));
	}
	
	dijkstra(1,x,n);
		
	sum=0;
	for(int i=1;i<=n;i++)
	sum=max(date[0][i]+date[1][i],sum);
	
	printf("%d\n",sum);

	return 0;
}

Posted by pspeakman on Thu, 01 Aug 2019 19:02:43 -0700