zoukankan      html  css  js  c++  java
  • hrbeu 哈工程 Minimum time

    这个OJ比较折腾,中文注释什么的都要注意,本来代码是1Y的,但是因为中文注释的问题CE和TLE了无数次,把中文注释消掉一部分后就AC了,一位同学说是中文注释的换行问题,所以如果这个代码copy过去不能AC而是什么CE,TLE甚至WA的话,那不是代码的问题应该是一些细节问题,可以搞搞中文注释什么的大概就过了

    最短路径的变形

    给出有向边u->v,后面跟两个数据一个是走这条边要用的时间,之后是到达v点后会有红绿灯,每次红绿灯的时间,,一开始所有红绿灯都是从红灯开始的

    用dij算法来时间,具体的做法只是修改了一下dij算法的模板

    //判断红绿灯的方法是 当前是时间t和这个点的红绿灯时间w//(t/w)%2==1,为绿灯,即取下整后再模2为奇数

    //(t/w)%2==0,为红灯,即取下整后模2为偶数,还需要等待的时间为w-t%(2w)

    //所以写一个green_or_red()函数来判断红绿灯,返回0表示红灯还要等待,返回1表示绿灯可以直接离开

    //另外要注意有些点的红绿灯的时间为0,这个点相当于全部是绿灯不用等待,不能用green_or_red()函数来判断因为会除0出错,直接归为绿灯即可

     

    从出发开始计时,到达点v的时间知道,然后看此时是否是红灯,是的话要加上还需等待的时间才是真正到达这个点的时间,然后就没有什么特别了就是dij

     

    #include <stdio.h>
    #include <string.h>
    
    #define N 30
    #define INF 0x7fffffff
    struct graph
    {
            int t1,t2;
    }g[N][N];
    int n,m;
    int V0,V;
    int D[N],cov[N],path[N];
    
    int find(char node[] , char s[])
    {
            int i=1;
            if(node[i]=='\0')  //第一个顶点
            {
                    node[i]=s[0]; node[i+1]='\0';
                    return i;
            }
            for(i=1; node[i]!='\0'; i++) 
                    if(node[i]==s[0]) 
                            return i;
            node[i]=s[0]; 
            node[i+1]='\0';
            return i;
    
    }
    void input()
    {
            char s1[10],s2[10];
            char node[N];
            int i,j,t1,t2,x1,x2;
            scanf("%d",&m); 
            for(i=0; i<N; i++)
                    for(j=0; j<N; j++)
                            g[i][j].t1=g[i][j].t2=INF;
            memset(node,0,sizeof(node));
            for(i=1; i<=m; i++)
            {
                    scanf("%s%s%d%d",s1,s2,&t1,&t2);
                    x1=find(node,s1);
                    x2=find(node,s2);
                    g[x1][x2].t1=t1;
                    g[x1][x2].t2=t2;
            }
            n=strlen(node+1);
            scanf("%s%s",s1,s2);
            V0=find(node,s1);
            V=find(node,s2);
    /*
            printf("%d\n",n);
            printf("%s\n",node+1);
            for(i=1; i<=n; i++)
            {
                    for(j=1; j<=n; j++)
                            printf("%d\\%d ",g[i][j].t1,g[i][j].t2);
                    printf("\n");
            }
            printf("%d %d\n",V0,V);
    */
            return ;
    }
    int green_or_red(int t , int w) //0是红灯1是绿灯
    { return ((t/w)%2) ; }
    
    void init()
    {
            int i,tmp;
            for(i=1; i<=n; i++) 
            {
                    cov[i]=0;   //表示还没有找到i点的最短距离
                    path[i]=1;  //记录路径
                    D[i]=g[V0][i].t1;
                    if(g[V0][i].t1!=INF)  //即到i点有通路
                       if(g[V0][i].t2!=0 && !green_or_red(D[i],g[V0][i].t2) ) 
                           D[i]+=g[V0][i].t2-D[i]%g[V0][i].t2;
                    //红绿灯的时间不为0(否则会有除0错误),并且计算得到是红灯,要加上等待时间 
            }
            cov[V0]=1;  //源点的最短距不用求
            //for(i=1; i<=n; i++)
                    //printf("%d\n",D[i]);
    
            return ;
    }
    
    void DIJ()
    {
        int nn,i,min,k,tmp,wait;
        for(nn=1; nn<n; nn++) //个数,还要覆盖其余n-1个点,即求出其余n-1个点的最短距
        {
            min=INF; k=1;
            for(i=1; i<=n; i++)  if(!cov[i])//扫描所有点,找到还没有被覆盖并且距离最短的点
            if(D[i]<min)
            {
                min=D[i];
                k=i;
            }
            cov[k]=1; 
            for(i=1; i<=n; i++)  if(!cov[i])//更新所有n个点的最短距离
    {//g[k][i]+min < D[i] 原来的模板代码 if(g[k][i].t1!=INF) //存在通路k->i ,这样才会有红绿灯 { if(g[k][i].t2!=0 && !green_or_red(min+g[k][i].t1 , g[k][i].t2) ) //红绿灯时间不为0 { wait=g[k][i].t2-(min+g[k][i].t1)%g[k][i].t2; if(min+g[k][i].t1+wait < D[i]) { D[i]=min+g[k][i].t1+wait; path[i]=k; } } else //绿灯(包括了红绿灯时间为0和不为0但刚好遇到绿灯的情况),不用算等待时间 { if(min+g[k][i].t1 < D[i]) { D[i]=min+g[k][i].t1; path[i]=k; } } } } } return ; } void print_path(int i) { int j; if(i==V0) { printf("%d",i); return ; } print_path(path[i]); printf(" %d",i); return ; } void printfff() { int i; //for(i=1; i<=n; i++) //printf("D[%d]=%d\n",i,D[i]); printf("%d\n",D[V]); //print_path(V); } int main() { int T; scanf("%d",&T); while(T--) { input(); init(); DIJ(); printfff(); } return 0; }

    代码中记录了路径,题目并没有要求只是顺便练习一下,输出函数那里也有打印路径的代码不过不需要就注释掉了

     

  • 相关阅读:
    关于在windows平台下将应用制作成windows服务及服务依赖的感想
    mysql 变量赋值的三种方法
    如何上传本地jar至远程仓库供其他项目使用
    maven的标准
    修改idea的缓存
    前端的网站
    读取简单的xml
    IDEA 自动设置compile target变成1.5
    注解导出优化版(推荐,十分强大)
    Linux命令干货!!!最常用的命令
  • 原文地址:https://www.cnblogs.com/scau20110726/p/2753405.html
Copyright © 2011-2022 走看看