zoukankan      html  css  js  c++  java
  • [POJ3411] Paid Roads

    题意:N个城市,经过每条边有两种代价,一种是经过了这条边给定的城市,代价为Pi,另一种是直接到对面城市,代价为Ri,求小朋友从1~N的最小代价(注:边是有向的)

    题解:

    spfa

    dis[i][j]表示到i号城市经过了j状态城市的最小代价,直接搞搞傻逼转移就好了

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #define ll long long
    using namespace std;
    
    const int N = 11;
    
    int n,m,e_num,ans,inf;
    int nxt[N*2],to[N*2],h[N],dis[N][1<<N];
    bool in[N][1<<N];
    
    struct Edge {int c,a,b;}w[N*2];
    struct Node {int x,y;};
    
    queue<Node> q;
    
    void add(int x, int y, int c, int a, int b) {
      nxt[++e_num]=h[x],to[e_num]=y,w[e_num]=(Edge){c,a,b},h[x]=e_num;
    }
    
    int gi() {
      int x=0,o=1; char ch=getchar();
      while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
      if(ch=='-') o=-1,ch=getchar();
      while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
      return o*x;
    }
    
    void spfa() {
      memset(dis,63,sizeof(dis));
      ans=inf=dis[0][0];
      dis[1][1]=0,in[1][1]=0,q.push((Node){1,1});
      while(!q.empty()) {
        Node u=q.front();
        int x=u.x,y=u.y;
        in[x][y]=0,q.pop();
        for(int i=h[x]; i; i=nxt[i]) {
          int v=to[i];
          if(y&(1<<(w[i].c-1))) {
    	if(dis[x][y]+w[i].a<dis[v][y|(1<<(v-1))]) {
    	  dis[v][y|(1<<(v-1))]=dis[x][y]+w[i].a;
    	  if(!in[v][y|(1<<(v-1))]) in[v][y|(1<<(v-1))]=1,q.push((Node){v,y|(1<<(v-1))});
    	}
          }
          else {
    	if(dis[x][y]+w[i].b<dis[v][y|(1<<(v-1))]) {
    	  dis[v][y|(1<<(v-1))]=dis[x][y]+w[i].b;
    	  if(!in[v][y|(1<<(v-1))]) in[v][y|(1<<(v-1))]=1,q.push((Node){v,y|(1<<(v-1))});
    	}
          }
        }
      }
    }
    
    int main() {
      while(scanf("%d%d", &n, &m)!=EOF) {
        for(int i=1; i<=m; i++) {
          int x=gi(),y=gi(),c=gi(),a=gi(),b=gi();
          add(x,y,c,a,b);//add(y,x,c,a,b);   
        }
        spfa();
        for(int i=1; i<1<<n; i++) {
          ans=min(ans,dis[n][i]);
        }
        if(ans==inf) puts("impossible");
        else printf("%d
    ", ans);
      }
      return 0;
    }
    
  • 相关阅读:
    Ubuntu上使用Latex
    Ubuntu18.04 解压文件名乱码的解决方法
    Android 编译 opencv
    android 使用编译好的sdk
    https协议加密原理介绍(一)
    java 面试题目 class.forName和load的区别
    给进程设置环境变量
    Maven 编译jdk配置
    Docker积累
    潜谈单例模式
  • 原文地址:https://www.cnblogs.com/HLXZZ/p/7512014.html
Copyright © 2011-2022 走看看