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;
    }
    
  • 相关阅读:
    TCP三次握手
    PPP(P2P)协议
    TCP协议
    SQL Server Always ON 数据同步原理
    IP地址子网掩码网关DNS
    linux修改机器名
    sqlserver迁移到mysql遇到的那些坑
    sqlserver锁和隔离级别
    用Python登录好友QQ空间点赞
    Python变量赋值的秘密
  • 原文地址:https://www.cnblogs.com/May-2nd/p/15015204.html
Copyright © 2011-2022 走看看