zoukankan      html  css  js  c++  java
  • poj3114 强连通+最短路

    题意:有 n 个城市,城市之间能够通过邮件或者电子邮件传递消息,已知 m 条邮件线路,每条线路代表 A 能送邮件到 B,并且花费 V 时间,如果几个城市之间能够相互邮件送达,那么他们就在同一个国家内,他们之间就能够通过电子邮件传递消息,花费 0 时间。有 k 个询问,每次询问从点 a 到点 b 传送消息,最少需要花费多少时间。

    由于多个城市能够互相送邮件,那么就在同一国家,互相传递消息不需要花费,因此首先强连通缩点,然后再对每次询问求出解就行。我一开始认为强连通缩点后是有向无环图,直接 dfs 的话对于每个询问复杂度不会很大,但是结果T了,然后换成了每个询问求一次单源最短路,然后A掉了。

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<stack>
      4 #include<queue>
      5 #include<algorithm>
      6 #include<vector>
      7 using namespace std;
      8 typedef pair<int,int> pii;
      9 
     10 const int maxn=505;
     11 const int maxm=250005;
     12 const int INF=0x3f3f3f3f;
     13 
     14 int head[2][maxn],point[2][maxm],nxt[2][maxm],size[2],val[2][maxm];
     15 int n,t,scccnt;
     16 int stx[maxn],low[maxn],scc[maxn];
     17 int dis[maxn];
     18 stack<int>S;
     19 
     20 int min(int a,int b){return a<b?a:b;}
     21 
     22 void init(){
     23     memset(head,-1,sizeof(head));
     24     size[0]=size[1]=0;
     25 }
     26 
     27 void add(int a,int b,int v,int c=0){
     28     point[c][size[c]]=b;
     29     nxt[c][size[c]]=head[c][a];
     30     val[c][size[c]]=v;
     31     head[c][a]=size[c]++;
     32 }
     33 
     34 struct cmp{                    //将优先队列改为小根堆
     35     bool operator()(pii a,pii b){
     36         return a.first>b.first;
     37     }
     38 };
     39 
     40 void dij(int s,int t){            //传入出发点和到达点
     41     int i;
     42     priority_queue<pii,vector<pii>,cmp>q;
     43     q.push(make_pair(0,s));
     44     memset(dis,0x3f,sizeof(dis));
     45     dis[s]=0;
     46     while(!q.empty()){
     47         pii u=q.top();
     48         q.pop();
     49         if(u.first>dis[u.second])continue;
     50         for(i=head[1][u.second];~i;i=nxt[1][i]){
     51             int j=point[1][i];
     52             if(dis[j]>u.first+val[1][i]){
     53                 dis[j]=u.first+val[1][i];
     54                 q.push(make_pair(dis[j],j));
     55             }
     56         }
     57     }
     58     if(dis[t]==INF)printf("Nao e possivel entregar a carta
    ");
     59     else printf("%d
    ",dis[t]);
     60 }
     61 
     62 void dfs(int s){
     63     stx[s]=low[s]=++t;
     64     S.push(s);
     65     for(int i=head[0][s];~i;i=nxt[0][i]){
     66         int j=point[0][i];
     67         if(!stx[j]){
     68             dfs(j);
     69             low[s]=min(low[s],low[j]);
     70         }
     71         else if(!scc[j]){
     72             low[s]=min(low[s],stx[j]);
     73         }
     74     }
     75     if(low[s]==stx[s]){
     76         scccnt++;
     77         while(1){
     78             int u=S.top();S.pop();
     79             scc[u]=scccnt;
     80             if(s==u)break;
     81         }
     82     }
     83 }
     84 
     85 void setscc(){
     86     memset(stx,0,sizeof(stx));
     87     memset(scc,0,sizeof(scc));
     88     t=scccnt=0;
     89     for(int i=1;i<=n;++i)if(!stx[i])dfs(i);
     90     for(int i=1;i<=n;++i){
     91         for(int j=head[0][i];~j;j=nxt[0][j]){
     92             int k=point[0][j];
     93             if(scc[i]!=scc[k]){
     94                 add(scc[i],scc[k],val[0][j],1);
     95             }
     96         }
     97     }
     98 }
     99 
    100 int main(){
    101     int m;
    102     while(scanf("%d",&n)!=EOF&&n){
    103         scanf("%d",&m);
    104         init();
    105         while(m--){
    106             int a,b,v;
    107             scanf("%d%d%d",&a,&b,&v);
    108             add(a,b,v);
    109         }
    110         setscc();
    111         int k;
    112         scanf("%d",&k);
    113         while(k--){
    114             int a,b;
    115             scanf("%d%d",&a,&b);
    116             if(scc[a]==scc[b])printf("0
    ");
    117             else{
    118                 dij(scc[a],scc[b]);
    119             }
    120         }
    121         printf("
    ");
    122     }
    123     return 0;
    124 }
    View Code
  • 相关阅读:
    html 上传图片前预览
    php获取当月天数及当月第一天及最后一天、上月第一天及最后一天实现方法
    php 计算 pdf文件页数
    php 获取半年内每个月的订单数量, 总价, 月份
    php 获取两个数组之间不同的值
    小程序支付功能
    关于nginx的Job for nginx.service failed because the control process exited with error code.错误
    linux 安装 Apollo
    MongoDB待续。。。
    ABP vNext...待续
  • 原文地址:https://www.cnblogs.com/cenariusxz/p/4817542.html
Copyright © 2011-2022 走看看