Poj 3268 Silver Cow Party + Poj 1511 Invitation Cards (最短路反向建图)

本文介绍了如何使用Dijkstra算法在正向和反向图中计算最短路径,通过两个具体的POJ题目,展示了如何求解从特定节点出发的最大往返路径长度及所有节点到特定节点的最短路径总和。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Poj 3268 Silver Cow Party

题意:牛要去特定的牧场开舞会..其中要求去的路以及回来的最短路的和是最大的

思路:第一次利用dijstra求出从X到各点的最短距离,即为回来时的最短路。
然后所有的边反向,再进行一次dijstra求X到各点的最短路径。
第二次求出的最短路径也就是各点到X的最短路径,因为边已经反向,对于第二次从X到各点的最短路径正是
原图从各点到X的最短路径。

#include <cstdio>
#include <cstring> 
#include <algorithm> 
#include <queue>
using namespace std;

#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))

const int INF = 0x3fffffff;  //权值上限
const int MAXPT = 1002;       //顶点数上限
const int MAXEG = 100000*2+10;     //边数上限

//点存储1~n
class Dijkstra     /*邻接表 + 优先队列 + Dijkstra求最短路*/
{
private:
	int n,e,e1;
    int dis[2][MAXPT], head[2][MAXPT];
    int visit[MAXPT];

    struct Node
	{
		int v,dis;
        Node () {}
		Node (int _v,int _dis)
		{
			v=_v;
			dis=_dis;
		}
		bool operator < (const Node a) const
		{
			return dis>a.dis;
		}
	};
	
	struct Edge
	{
		int v, w, next;
		Edge () {}
		Edge (int _v, int _next, int _w)
		{
			v=_v;
			next=_next;
			w=_w;
		}
    }edges[2][MAXEG];

public:
    inline void init (int vx)
	{
        n = vx;
		e = 0,e1=0; 
        memset(head[0],-1,sizeof(int) * (vx + 1));
		memset(head[1],-1,sizeof(int) * (vx + 1));
    } 

    inline void Add (int u, int v, int w)
	{ 
        edges[0][e] = Edge(v, head[0][u], w);
        head[0][u] = e++;
    } 

	inline void Add1 (int u, int v, int w)
	{ 
        edges[1][e1] = Edge(v, head[1][u], w);
        head[1][u] = e1++;
    } 
  
    void dijkstra (int flag,int src)
	{ 
        Node first, next;
        priority_queue <Node> Q;
        for (int i=0;i<=n;i++)
		{ 
            dis[flag][i] = INF; 
            visit[i] = false; 
        } 
  
        dis[flag][src]=0; 
        Q.push (Node(src, 0));
  
        while (!Q.empty())
		{ 
            first = Q.top(); 
            Q.pop(); 
            visit[first.v] = true;
  
            for (int i=head[flag][first.v] ; i!=-1 ; i=edges[flag][i].next)
			{ 
                if (visit[edges[flag][i].v])
					continue; 
                next = Node(edges[flag][i].v, first.dis + edges[flag][i].w);
                if (next.dis < dis[flag][next.v])
				{ 
                    dis[flag][next.v] = next.dis; 
                    Q.push(next); 
                } 
            } 
        }
    }

	int Deal (int x)
	{
		dijkstra (0,x);
		dijkstra (1,x);
		int ans=-1;
		for (int i=1;i<=n;i++)
			ans=max(ans,dis[0][i]+dis[1][i]);
		return ans;
	}

}ob; 


int main ()
{
#ifdef ONLINE_JUDGE
#else
	freopen("read.txt","r",stdin);
#endif
    int n,m,x;
	while (~scanf("%d%d%d",&n,&m,&x))
	{
		ob.init(n);
		while (m--)
		{
			int u,v,w;
			scanf("%d%d%d",&u,&v,&w);
			ob.Add(u,v,w);   //正图加边
			ob.Add1(v,u,w);  //反图加边
        }
		printf("%d\n",ob.Deal (x));
	}
	return 0; 
}


Poj 1511 Invitation Cards 

题意:在一个有向图中,设原点为1,求所有点到1的最短路之和与1到所有点最短路之和的和。

思路:源点到其他点的最短距离可在原图中用spfa求出,其他点到源点最短距离可在逆图中用spfa求出。

#include <cstdio>
#include <cstring> 
#include <algorithm> 
#include <queue>
using namespace std;

#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))

const int INF = 0x3fffffff;  //权值上限
const int MAXPT = 1000005;       //顶点数上限
const int MAXEG = 1000005;     //边数上限

//点存储1~n
class Dijkstra     /*邻接表 + 优先队列 + Dijkstra求最短路*/
{
private:
	int n,e,e1;
    int dis[2][MAXPT], head[2][MAXPT];
    int visit[MAXPT];

    struct Node
	{
		int v,dis;
        Node () {}
		Node (int _v,int _dis)
		{
			v=_v;
			dis=_dis;
		}
		bool operator < (const Node a) const
		{
			return dis>a.dis;
		}
	};
	
	struct Edge
	{
		int v, w, next;
		Edge () {}
		Edge (int _v, int _next, int _w)
		{
			v=_v;
			next=_next;
			w=_w;
		}
    }edges[2][MAXEG];

public:
    inline void init (int vx)
	{
        n = vx;
		e = 0,e1=0; 
        memset(head[0],-1,sizeof(int) * (vx + 1));
		memset(head[1],-1,sizeof(int) * (vx + 1));
    } 

    inline void Add (int u, int v, int w)
	{ 
        edges[0][e] = Edge(v, head[0][u], w);
        head[0][u] = e++;
    } 

	inline void Add1 (int u, int v, int w)
	{ 
        edges[1][e1] = Edge(v, head[1][u], w);
        head[1][u] = e1++;
    } 
  
    void dijkstra (int flag,int src)
	{ 
        Node first, next;
        priority_queue <Node> Q;
        for (int i=0;i<=n;i++)
		{ 
            dis[flag][i] = INF; 
            visit[i] = false; 
        } 
  
        dis[flag][src]=0; 
        Q.push (Node(src, 0));
  
        while (!Q.empty())
		{ 
            first = Q.top(); 
            Q.pop(); 
            visit[first.v] = true;
  
            for (int i=head[flag][first.v] ; i!=-1 ; i=edges[flag][i].next)
			{ 
                if (visit[edges[flag][i].v])
					continue; 
                next = Node(edges[flag][i].v, first.dis + edges[flag][i].w);
                if (next.dis < dis[flag][next.v])
				{ 
                    dis[flag][next.v] = next.dis; 
                    Q.push(next); 
                } 
            } 
        }
    }

	__int64 Deal (int x)
	{
		dijkstra (0,x);
		dijkstra (1,x);
		__int64 ans=0;
		for (int i=1;i<=n;i++)
			ans+=dis[0][i]+dis[1][i];
		return ans;
	}

}ob; 


int main ()
{
#ifdef ONLINE_JUDGE
#else
	freopen("read.txt","r",stdin);
#endif
    int T;
    scanf("%d",&T);
    for (int Cas=1;Cas<=T;Cas++)
    {
		int n,m;
		scanf("%d%d",&n,&m);
		ob.init(n);
		while (m--)
		{
			int u,v,w;
			scanf("%d%d%d",&u,&v,&w);
			ob.Add(u,v,w);   //正图加边
			ob.Add1(v,u,w);  //反图加边
        }
		printf("%I64d\n",ob.Deal (1));
	}
	return 0; 
}



内容概要:该研究通过在黑龙江省某示范村进行24小时实地测试,比较了燃煤炉具与自动/手动进料生物质炉具的污染物排放特征。结果显示,生物质炉具相比燃煤炉具显著降低了PM2.5、CO和SO2的排放(自动进料分别降低41.2%、54.3%、40.0%;手动进料降低35.3%、22.1%、20.0%),但NOx排放未降低甚至有所增加。研究还发现,经济性和便利性是影响生物质炉具推广的重要因素。该研究不仅提供了实际排放数据支持,还通过Python代码详细复现了排放特征比较、减排效果计算和结果可视化,进一步探讨了燃料性质、动态排放特征、碳平衡计算以及政策议。 适合人群:从事环境科学研究的学者、政府环保部门工作人员、能源政策制定者、关注农村能源转型的社会人士。 使用场景及目标:①评估生物质炉具在农村地区的推广潜力;②为政策制定者提供科学依据,优化补贴政策;③帮助研究人员深入了解生物质炉具的排放特征和技术改进方向;④为企业研发更高效的生物质炉具提供参考。 其他说明:该研究通过大量数据分析和模拟,揭示了生物质炉具在实际应用中的优点和挑战,特别是NOx排放增加的问题。研究还提出了多项具体的技术改进方向和政策议,如优化进料方式、提高热效率、设本地颗粒厂等,为生物质炉具的广泛推广提供了可行路径。此外,研究还开发了一个智能政策议生成系统,可以根据不同地区的特征定制化生成政策议,为农村能源转型提供了有力支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值