zoukankan      html  css  js  c++  java
  • POJ1511 Invitation Cards SPFA算法裸题变形

       

    原题目:http://poj.org/problem?id=1511

        给出一个有向图,求出这个图从1到所有点的最短路径和所有点到1的最短路径的和。

        这题数据量有点大,数据范围也大,所以用SPFA+邻接表做。

        各种限制:Time Limit: 8000MS    Memory Limit: 262144K(折腾评测机概念啊)

        输入没什么处理的,注意在求所有点到1最短路径和的思想,嫑一看每个点都要是源点Floyd去了。。你想想,只要你把有向图所有箭头改一个方向,不又是从1到所有点的最短路径了么!?

        废话不多说,贴代码!C++

        这里我用了两个命名空间来防止重复,内容其实是一模一样的,(那我XX啊,直接一个类两个实例不就得了啊!不过这么写了就写了吧)用的STL的容器队列,SPFA,数组邻接表,会点SPFA都能看懂吧。好像是两秒多AC的,内存也不大。

    因为数据范围太大,我们就用long long做的,不过为了省内存,我把不需要long long的地方都没有long long(我一同学除了_N用的int别的都用的long long,内存比我多)

       

    //Accepted
    #include <iostream>
    #include <stdio.h>
    #include <cstring>
    #include <queue>
    using namespace std;
    
    const int MAXN=1000000+10;
    struct Edge
    {
    	int v,w,next;
    };
    		int m,n;
    namespace sp1
    {
    	Edge a[MAXN];
    	int link[MAXN];
    	bool visit[MAXN];
    	long long d[MAXN];
    	queue<int> q;
    	void memoryset()
    	{
    		memset(a,0,sizeof(a));
    		memset(link,0,sizeof(link));
    		memset(visit,0,sizeof(visit));
    		memset(d,0x3f,sizeof(d));
    	}
    	void add(int u,int v,int w)
    	{
    		static int tmp=1;
    		a[tmp].v=v;
    		a[tmp].w=w;
    		a[tmp].next=link[u];
    		link[u]=tmp;
    		tmp++;
    	}
    	void spfa()
    	{
    		q.push(1);
    		visit[1]=true;
    		d[1]=0;
    		while(!q.empty())
    		{
    			int x=q.front();
    			q.pop();
    			visit[x]=false;
    			for(int i=link[x];i!=0;i=a[i].next)
    			{
    				if(d[x]+a[i].w<d[a[i].v])
    				{
    					d[a[i].v]=d[x]+a[i].w;
    					if(visit[a[i].v]==false)
    					{
    						q.push(a[i].v);
    						visit[a[i].v]=true;
    					}
    				}
    			}
    		}
    	}
    };
    namespace sp2
    {
    	Edge a[MAXN];
    	int link[MAXN];
    	bool visit[MAXN];
    	long long d[MAXN];
    	queue<int> q;
    	void memoryset()
    	{
    		memset(a,0,sizeof(a));
    		memset(link,0,sizeof(link));
    		memset(visit,0,sizeof(visit));
    		memset(d,0x3f,sizeof(d));
    	}
    	void add(int u,int v,int w)
    	{
    		static int tmp=1;
    		a[tmp].v=v;
    		a[tmp].w=w;
    		a[tmp].next=link[u];
    		link[u]=tmp;
    		tmp++;
    	}
    	void spfa()
    	{
    		q.push(1);
    		visit[1]=true;
    		d[1]=0; 
    		while(!q.empty())
    		{
    			int x=q.front();
    			q.pop();
    			visit[x]=false;
    			for(int i=link[x];i!=0;i=a[i].next)
    			{
    				if(d[x]+a[i].w<d[a[i].v])
    				{
    					d[a[i].v]=d[x]+a[i].w;
    					if(visit[a[i].v]==false)
    					{
    						q.push(a[i].v);
    						visit[a[i].v]=true;
    					}
    				}
    			}
    		}
    	}
    };
    int main()
    {
    	int _N;
    	scanf("%d",&_N);
    	while(_N--)
    	{
    
    		scanf("%d%d",&n,&m);
    		sp1::memoryset();
    		sp2::memoryset();
    		for(int i=1;i<=m;i++)
    		{
    			int a,b,c;
    			scanf("%d%d%d",&a,&b,&c);
    			sp1::add(a,b,c);
    			sp2::add(b,a,c);
    		}
    		sp1::spfa();
    		sp2::spfa();
    		long long ans=0;
    		for(int i=1;i<=n;i++)
    			ans+=sp1::d[i];
    		for(int i=1;i<=n;i++)
    			ans+=sp2::d[i];
    		cout << ans << endl;
    	}
    }
    

     //以下是6月7号补充

    我写了俩一模一样代码,注意是一模一样。。(猛的拍头)你不用一个类来封装啊!于是因为我懒就不写代码啦。。自己测了一下,一个SP的实例大小为25000296Bytes。。所以大家写的时候必须把SP的实例放全局,否则爆栈,否则爆栈,否则爆栈,否则爆栈,否则爆栈。。。

  • 相关阅读:
    提高C#编程水平的50个要点
    纯CSS Tooltips..
    分支结构程序设计
    个性测试题
    CSS与DIV
    数据库设计中的14个技巧
    XML文档处理(树的应用)
    使用设计模式构建通用数据库访问类
    什么样简历最受名企欢迎?
    如何做需求分析
  • 原文地址:https://www.cnblogs.com/oier/p/5560415.html
Copyright © 2011-2022 走看看