zoukankan      html  css  js  c++  java
  • P2149 [SDOI2009]Elaxia的路线

    如果两人的有向路径交既有同向边,也有反向边。因为最短路径是链,所以必定有人走的不是最短路。

    并且在满足都是同向或者都是反向的前提下,有向路径交只要在两人的最短路径有向无环图上,就一定是合法的。因为有向路径交如果不能被一条链覆盖,就说明必须多绕路,同样与最短路径不符。

    先选一个人搞出它起点到终点的最短路径有向无环图,然后另一个人再拓扑排序,同向和反向各算一遍取 (max) 即可。

    注意拓扑排序考虑入度时不在最短路径有向无环图中的点不能算在内,这个可以一遍 DFS 处理出来。

    code:

    #include<bits/stdc++.h>
    using namespace std;
    #define N 1505
    #define Max(x,y)((x)>(y)?x:y)
    #define For(i,x,y)for(i=x;i<=(y);i++)
    struct node
    {
    	int next,to,w,type;
    }e[2250005];
    bool bo[N];
    queue<int>que;
    int head[N],dis[N],deg[N],len[N],g=1,n,mx;
    inline void add(int u,int v,int w)
    {
    	e[++g].w=w;
    	e[g].to=v;
    	e[g].next=head[u];
    	head[u]=g;
    }
    void SPFA(int s)
    {
    	int i,u,v;
    	For(i,1,n)dis[i]=INT_MAX>>1;
    	que.push(s);
    	dis[s]=0;
    	while(!que.empty())
    	{
    		u=que.front();
    		bo[u]=0;
    		for(i=head[u];i;i=e[i].next)
    		{
    			v=e[i].to;
    			if(dis[v]>dis[u]+e[i].w)
    			{
    				dis[v]=dis[u]+e[i].w;
    				if(!bo[v])que.push(v),bo[v]=1;
    			}
    		}
    		que.pop();
    	}
    }
    void dfs1(int u)
    {
    	if(bo[u])return;
    	int i,v;
    	bo[u]=1;
    	for(i=head[u];i;i=e[i].next)
    	{
    		v=e[i].to;
    		if(dis[u]==dis[v]+e[i].w)
    		{
    			e[i].type=2;
    			e[i^1].type=1;
    			dfs1(v);
    		}
    	}
    }
    void dfs2(int u,int rem)
    {
    	int i,v;
    	mx=Max(mx,len[u]);
    	for(i=head[u];i;i=e[i].next)
    	{
    		v=e[i].to;
    		if(dis[u]==dis[v]+e[i].w)
    		{
    			/*printf("%d %d %d
    ",u,v,deg[v]);*/
    			deg[v]--;
    			len[v]=Max(len[v],len[u]+(e[i].type==rem)*e[i].w);
    			if(!deg[v])dfs2(v,rem);
    		}
    	}
    }
    void dfs3(int u)
    {
    	if(bo[u])return;
    	int i,v;
    	bo[u]=1;
    	for(i=head[u];i;i=e[i].next)
    	{
    		v=e[i].to;
    		if(dis[u]==dis[v]+e[i].w)dfs3(v);
    	}
    }
    int main()
    {
    	int m,x,xx,y,yy,u,v,w,i;
    	scanf("%d%d%d%d%d%d",&n,&m,&x,&y,&xx,&yy);
    	while(m--)
    	{
    		scanf("%d%d%d",&u,&v,&w);
    		add(u,v,w),add(v,u,w);
    	}
    	SPFA(x);
    	dfs1(y);
    	For(i,1,n)bo[i]=0;
    	SPFA(xx);
    	For(i,1,n)bo[i]=0;
    	dfs3(yy);
    	For(u,1,n)
    	for(i=head[u];i;i=e[i].next)
    	if(bo[e[i].to])deg[u]+=dis[e[i].to]-e[i].w==dis[u];
    	dfs2(yy,1);
    	For(u,1,n)
    	{
    		len[u]=deg[u]=0;
    		for(i=head[u];i;i=e[i].next)
    		if(bo[e[i].to])deg[u]+=dis[e[i].to]-e[i].w==dis[u];
    	}
    	dfs2(yy,2);
    	printf("%d",mx);
    	return 0;
    }
    
  • 相关阅读:
    UVA 12657 Boxes in a Line 双向链表模拟
    C语言单片和C#语言服务器端DES及3DES加密的实现
    关于TcpClient,Socket连接超时的几种处理方法
    拿来参考的学习计划
    faire la course
    今日法语2
    炸鱼
    今日法语
    今日疑问
    下周想做的菜
  • 原文地址:https://www.cnblogs.com/May-2nd/p/15015204.html
Copyright © 2011-2022 走看看