zoukankan      html  css  js  c++  java
  • bzoj2763:最短路

    最短路,然后可以有多次免费的机会,不难写,但是最短路这次试着用指针写果然快了点,一开始看错数据范围数组开太大tle;

    ----------------------------------------------------------------------------------------------

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define rep(i,n) for(int i=1;i<=n;i++)
    #define clr(x,c) memset(x,c,sizeof(x))
    #define adde(u,v,w) add(u,v,w),add(v,u,w)


    int read(){
       int x=0;
       char c=getchar();
       int f=1;
       while(!isdigit(c)){
          if(c=='-') f=-1;
          c=getchar();
       }
       while(isdigit(c)){
          x=x*10+c-'0';
          c=getchar();
       }
       return x*f;
    }


    struct edge{
        int to,d;
        edge*next;
    };
    edge*pt,edges[50005*2];
    edge*head[10005];
    int n,m,k,s,t;
    int dis[10005][15];


    struct node{
     int x,k,d;
     node(int _x,int _k,int _d):x(_x),k(_k),d(_d){};
     bool operator<(const node&rhs)const{
       return d>rhs.d;}
    };
    priority_queue<node>q;


    void add(int u,int v,int w){
       pt->to=v;
       pt->d=w;
       pt->next=head[u];
       head[u]=pt++;
    }


    void dijkstra(){
       clr(dis,0x3f);
       clr(dis[s],0);
       q.push(node(s,0,0));
       rep(i,k)
            q.push(node(s,i,0));
       while(!q.empty()){
        node o=q.top();
        q.pop();
        if(o.d!=dis[o.x][o.k]) continue;
        for(edge*e=head[o.x];e;e=e->next){
            int to=e->to;
            if(dis[o.x][o.k]+e->d<dis[to][o.k]){
                 dis[to][o.k]=dis[o.x][o.k]+e->d;
                 q.push(node(to,o.k,dis[to][o.k]));
             }
            if(dis[o.x][o.k]<dis[to][o.k+1]&&o.k<k){
                 dis[to][o.k+1]=dis[o.x][o.k];
                 q.push(node(to,o.k+1,dis[to][o.k+1]));
            }
         }
       }
    }
    int main(){
       /*freopen("test.in","r",stdin);
       freopen("test.out","w",stdout);*/
       scanf("%d%d%d%d%d",&n,&m,&k,&s,&t);
       s++,t++;
       clr(head,0);
       pt=edges;
       rep(i,m){
          int u=read(),v=read(),w=read();
          u++,v++;
          adde(u,v,w);
       }
       /*rep(i,n){
              printf("%d ",i);
             for(edge*e=head[i];e;e=e->next){
                   printf("%d %d ",e->to,e->d);
             }
         }*/
       dijkstra();
       int ans=dis[t][0];
       rep(i,k){
            ans=min(ans,dis[t][i]);
        }
        printf("%d ",ans);
        //fclose(stdin);fclose(stdout);
        return 0;
    }

    ----------------------------------------------------------------------------------------------

    2763: [JLOI2011]飞行路线

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 1448  Solved: 551
    [Submit][Status][Discuss]

    Description

    Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司。该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定的价格。Alice和Bob现在要从一个城市沿着航线到达另一个城市,途中可以进行转机。航空公司对他们这次旅行也推出优惠,他们可以免费在最多k种航线上搭乘飞机。那么Alice和Bob这次出行最少花费多少?

    Input

    数据的第一行有三个整数,n,m,k,分别表示城市数,航线数和免费乘坐次数。
    第二行有两个整数,s,t,分别表示他们出行的起点城市编号和终点城市编号。(0<=s,t<n)
    接下来有m行,每行三个整数,a,b,c,表示存在一种航线,能从城市a到达城市b,或从城市b到达城市a,价格为c。(0<=a,b<n,a与b不相等,0<=c<=1000)
     

    Output

     
    只有一行,包含一个整数,为最少花费。

    Sample Input

    5 6 1
    0 4
    0 1 5
    1 2 5
    2 3 5
    3 4 5
    2 3 3
    0 2 100

    Sample Output

    8

    HINT

    对于30%的数据,2<=n<=50,1<=m<=300,k=0;

    对于50%的数据,2<=n<=600,1<=m<=6000,0<=k<=1;

    对于100%的数据,2<=n<=10000,1<=m<=50000,0<=k<=10.

    Source

     
    [Submit][Status][Discuss]
  • 相关阅读:
    winform解析json API数据
    c#(winform)获取本地打印机
    winform程序post提交数据API
    C#关于panle重叠
    net面试总结的题目
    委托
    最实用JS 留着学习
    dev 控件获得所有的EFDEVGRID
    c#利用WebClient和WebRequest获取网页源代码的比较
    浅谈.Net WebService开发
  • 原文地址:https://www.cnblogs.com/20003238wzc--/p/5017677.html
Copyright © 2011-2022 走看看