zoukankan      html  css  js  c++  java
  • bzoj 1774: [Usaco2009 Dec]Toll 过路费【排序+Floyd】

    非常迷的一道题啊
    我觉得挺对的版本只得了30
    总之就是Floyd·改,开两个数组,一个是d[i][j]就是普通的只有边权的最短路,a[i][j]是题目要求的那种
    具体改的地方是把枚举中转点的地方把中转点按从小到大的顺序枚举,d[i][j]按照套路更新即可,然后a[i][j]从a[i][j]原数和d[i][j]+max(c[i],c[j],c[中转点])中取min
    证明的话是最短路不一定是最终答案,能更新这个答案的一定是最大点更小一些的另一条路,所以按点权顺序更新能保证把这种情况全部更新

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=255,inf=1e9+7;
    int n,m,q,a[N][N],d[N][N],v[N];
    struct qwe
    {
    	int p,v;
    }c[N];
    bool cmp(const qwe &x,const qwe &y)
    {
    	return x.v<y.v;
    }
    int read()
    {
    	int r=0,f=1;
    	char p=getchar();
    	while(p>'9'||p<'0')
    	{
    		if(p=='-')
    			f=-1;
    		p=getchar();
    	}
    	while(p>='0'&&p<='9')
    	{
    		r=r*10+p-48;
    		p=getchar();
    	}
    	return r*f;
    }
    int main()
    {
    	n=read(),m=read(),q=read();
    	for(int i=1;i<=n;i++)
    		v[i]=d[i][i]=a[i][i]=c[i].v=read(),c[i].p=i;
    	sort(c+1,c+1+n,cmp);
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=n;j++)
    			if(i!=j)
    				a[i][j]=d[i][j]=inf;
    	for(int i=1;i<=m;i++)
    	{
    		int x=read(),y=read(),z=read();
    		d[x][y]=d[y][x]=min(d[x][y],z);
    	}
    	for(int k=1;k<=n;k++)
    		for(int i=1;i<=n;i++)
    			for(int j=1;j<=n;j++)
    				d[i][j]=min(d[i][j],d[i][c[k].p]+d[c[k].p][j]),a[i][j]=min(a[i][j],d[i][j]+max(max(v[i],v[j]),c[k].v));
    	while(q--)
    	{
    		int x=read(),y=read();
    		printf("%d
    ",a[x][y]);
    	}
    	return 0;
    }
    

    我觉得挺对的版本:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    const int N=255,inf=1e9+7;
    int n,m,q,a[N][N],c[N],mx[N][N];
    int read()
    {
        int r=0,f=1;
        char p=getchar();
        while(p>'9'||p<'0')
        {
            if(p=='-')
                f=-1;
            p=getchar();
        }
        while(p>='0'&&p<='9')
        {
            r=r*10+p-48;
            p=getchar();
        }
        return r*f;
    }
    int main()
    {
        n=read(),m=read(),q=read();
        for(int i=1;i<=n;i++)
            c[i]=read(),mx[i][i]=a[i][i]=c[i];
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                if(i!=j)
                    a[i][j]=mx[i][j]=inf;
        for(int i=1;i<=m;i++)
        {
            int x=read(),y=read(),z=read();
            if(a[x][y]>z+max(c[x],c[y]))
                a[x][y]=a[y][x]=z+max(c[x],c[y]),mx[x][y]=mx[y][x]=max(c[x],c[y]);
        }
        for(int k=1;k<=n;k++)
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    if(a[i][j]>a[i][k]-mx[i][k]+a[k][j]-mx[k][j]+max(mx[i][k],mx[k][j]))
                        a[i][j]=a[i][k]-mx[i][k]+a[k][j]-mx[k][j]+max(mx[i][k],mx[k][j]),mx[i][j]=max(mx[i][k],mx[k][j]);
        while(q--)
        {
            int x=read(),y=read();
            printf("%d
    ",a[x][y]);
        }
        return 0;
    }
    
  • 相关阅读:
    JavaScript事件详解
    JavaScript事件
    十六进制转十进制原理
    java:数组复制
    java:数组扩容
    MySQL---Day2
    Pyhton学习——Day47
    MySQL---Day1
    Pyhton学习——Day46
    Someing-About-Work
  • 原文地址:https://www.cnblogs.com/lokiii/p/9254897.html
Copyright © 2011-2022 走看看