zoukankan      html  css  js  c++  java
  • p1355

    好久没写题解了,都怪这道题!

    正解好像可以写矩阵乘法,但是!

    本题n看似很大,但是考虑最优解一定是跑到一个顶点后在这个边上来回跑,然后看看跑的差不多了再去终点.

    这个边一定是最短边么?不一定的,反例可以随便找啦.

    这算离散化么...不懂

    那么n就可以缩小到T^2了.而且T<=100,每个点有两条边,点最多也就是一整个环,100个点.

    这么小的图就可以随便搞了.

    那么我们的任务就是处理起点到每个点i走k条边的最短路ds[i][k],终点到每个点i走k条边的最短距离de[i][k].这个处理如果用dfs的话是会超时的,但是可以用类似动态规划的东西

    de[i][k]=min(de[e[j].y][k-1]+e[j].v),e[j].x=i;

    这样跑一遍的复杂度是T*T,因为每次更新k的距离时T条边总会用两次,即用x更新y,用y更新x.而且图上两个点的最短路最多用T个边,否则一定重复走了某一个边.

    然后我们考虑在哪个边上来回跑,这个是不能直接确定的,只好遍历一下.然后考虑用长为几的最短路,这个也不能确定,要搞双重循环.即使如此,复杂度还是优秀的T^3.

    我之所以被卡这么长时间的原因完全是初始量不会设,以为自己设的足够大了,但是还是不够用.

    using namespace std;
    int i,f,k,j,tx,ty,tv,k1,k2;
    int n,T,S,E,sum;
    struct node
    {
        int x,y;
        long long v;
        int next;
    }e[210];
    int tot,head[110];
    long long  de[110][110],ds[110][110],t;
    int tt[1010];
    long long ans;
    void add(int x,int y,long long v)
    {
        tot++;
        e[tot].x=x;
        e[tot].y=y;
        e[tot].v=v;
    }
    long long max(long long a,long long b)
    {
        return a>b?a:b;
    }
    inline int read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int main()
    {
        n=read();T=read();S=read();E=read();
        for(i=1;i<=T;i++)
        {
            tv=read();tx=read();ty=read();
            tt[tx]=tt[ty]=1;
            add(tx,ty,tv);
            add(ty,tx,tv);
            
        }
        for(i=1;i<=1000;i++)
            if(tt[i])
                sum++,tt[i]=sum;
        S=tt[S];
        E=tt[E];
    
        for(i=1;i<=tot;i++)
        {
            e[i].x=tt[e[i].x];
            e[i].y=tt[e[i].y];
            e[i].next=head[e[i].x];
            head[e[i].x]=i;
        }
        //cout<<sum<<' ';
        for(i=1;i<=sum;i++)
        {
            for(k=0;k<=T;k++)
                ds[i][k]=de[i][k]=400000000;
        }
        ans=1000000000;
        ds[S][0]=0;
        de[E][0]=0;
        for(k=1;k<=T;k++)
            for(i=1;i<=sum;i++)
                for(j=head[i];j;j=e[j].next)
                {
                    ds[i][k]=min(ds[i][k],ds[e[j].y][k-1]+e[j].v);
                    de[i][k]=min(de[i][k],de[e[j].y][k-1]+e[j].v);
                }
        for(i=1;i<=tot;i++)
        {
            for(k1=0;k1<=T;k1++)
                for(k2=0;k2<=T;k2++)
                {
                    t=n-k1-k2;
                    if(t%2==0||t<0)continue;
                    t=t*e[i].v;
                    ans=min(ans,de[e[i].x][k1]+ds[e[i].y][k2]+t);
                    ans=min(ans,de[e[i].y][k1]+ds[e[i].x][k2]+t);
                }
        }
        cout<<ans;
        
    
    }
  • 相关阅读:
    服务器迁移总结
    使用OpenSSL生成证书
    mysql Event、存储过程、表命令
    负载均衡 > 常见问题
    SpringMVC记住密码功能
    spring mvc +cookie+拦截器功能 实现系统自动登陆
    android studio之argument for @notnull parameter 'name'
    jQuery ajax表单提交实现局部刷新
    Spring MVC 中采用注解方式 Action中跳转到另一个Action的写法
    ajax表单提交全路径
  • 原文地址:https://www.cnblogs.com/qywyt/p/9717990.html
Copyright © 2011-2022 走看看