• bzoj 1880: [Sdoi2009]Elaxia的路线【spfa+拓扑排序】


    有趣啊
    先spfa分别求出以s1,t1,s2,t2为起点的最短路,然后把在s1-->t1或者s2-->t2最短路上的边重新建有向图,跑拓扑最长路即可

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<vector>
    using namespace std;
    const int N=1505,inf=1e9;
    int n,m,x1,x2,y1,y2,d[N],dis[N],h[N],cnt,s1[N],s2[N],t1[N],t2[N];
    bool v[N];
    struct qwe
    {
        int ne,no,to,va;
    }e[1000005];
    struct bian
    {
    	int u,v,w;
    	bian(int U=0,int V=0,int W=0)
    	{
    		u=U,v=V,w=W;
    	}
    };
    vector<bian>ve;
    void add(int u,int v,int w)
    {
    	cnt++;
        e[cnt].ne=h[u];
        e[cnt].no=u;
        e[cnt].to=v;
        e[cnt].va=w;
        h[u]=cnt;
    }
    void spfa(int s,int dis[])
    {
    	queue<int>q;
        for(int i=1;i<=n;i++)
    		dis[i]=inf,v[i]=0;
        dis[s]=0;
    	v[s]=1;
        q.push(s);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            v[u]=0;
            for(int i=h[u];i;i=e[i].ne)
                if(dis[e[i].to]>dis[u]+e[i].va)
                {
                    dis[e[i].to]=dis[u]+e[i].va;
                    if(!v[e[i].to])
    				{
    					v[e[i].to]=1;
                        q.push(e[i].to);
    				}
                }
        }
    }
    int main()
    {
        scanf("%d%d%d%d%d%d",&n,&m,&x1,&y1,&x2,&y2);
        for(int i=1,x,y,v;i<=m;i++)
        {
            scanf("%d%d%d",&x,&y,&v);
            add(x,y,v),add(y,x,v);
        }
        spfa(x1,s1);
        spfa(y1,t1);
        spfa(x2,s2);
        spfa(y2,t2);
        for(int i=1;i<=cnt;i+=2)
            if(min(s1[e[i].no],s1[e[i].to])+min(t1[e[i].to],t1[e[i].no])+e[i].va==s1[y1]&&min(s2[e[i].no],s2[e[i].to])+min(t2[e[i].no],t2[e[i].to])+e[i].va==s2[y2])
            {
                if(s1[e[i].no]<s1[e[i].to])
    				ve.push_back(bian(e[i].no,e[i].to,e[i].va));
                else
    				ve.push_back(bian(e[i].to,e[i].no,e[i].va));
            }
    	memset(h,0,sizeof(h));
    	cnt=0;
    	for(int i=0;i<ve.size();i++)
    		add(ve[i].u,ve[i].v,ve[i].w),d[ve[i].v]++;
    	queue<int>q;
        for(int i=1;i<=n;i++)
        {
            dis[i]=0;
            if(!d[i]) 
    			q.push(i);
        }
        int ans=0;
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            for(int i=h[u];i;i=e[i].ne)
            {
                dis[e[i].to]=max(dis[e[i].to],dis[u]+e[i].va);
                ans=max(ans,dis[e[i].to]);
                d[e[i].to]--;
                if(!d[e[i].to]) 
    				q.push(e[i].to);
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    ASP.NET中级学习3
    C#面向对象学习笔记
    Javascript学习笔记
    FormView控件使用
    ASP.NET初级学习
    ListView控件是使用
    Java NIO 学习笔记一
    堆栈和托管堆 c#
    安装php7.2并且整合nginx且分开部署
    Python 安装requests和MySQLdb
  • 原文地址:https://www.cnblogs.com/lokiii/p/9639662.html
Copyright © 2020-2023  润新知