POJ 3114 Countries in War(强联通分量+Tarjan)

题目链接

题意 : 给你两个城市让你求最短距离,如果两个城市位于同一强连通分量中那距离为0.

思路 :强连通分量缩点之后,求最短路。以前写过,总感觉记忆不深,这次自己敲完再写了一遍。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <iostream>
  4 #include <vector>
  5 #include <stack>
  6 #include <queue>
  7 #include <algorithm>
  8 #define maxn 505
  9 using namespace std ;
 10
 11 struct node
 12 {
 13     int u,v,w,next ;
 14 } edge[maxn*maxn];
 15 int p[maxn][maxn];
 16 int dfn[maxn],low[maxn],head[maxn] ,vis[maxn],dis[maxn],belong[maxn];
 17 int timee,cnt ,cntt,n,m;
 18 stack<int>stk ;
 19
 20 void Init()
 21 {
 22     timee = 0 ;
 23     cnt = cntt = 0 ;
 24     memset(dfn,0,sizeof(dfn)) ;
 25     memset(low,0,sizeof(low)) ;
 26     memset(dis,0,sizeof(dis)) ;
 27     memset(head,-1,sizeof(head)) ;
 28     memset(vis,0,sizeof(vis)) ;
 29     memset(p,0x3f,sizeof(p)) ;
 30 }
 31 void addedge(int u,int v,int w)
 32 {
 33     edge[cnt].u = u ;
 34     edge[cnt].v = v ;
 35     edge[cnt].w = w ;
 36     edge[cnt].next = head[u] ;
 37     head[u] = cnt++ ;
 38 }
 39 void tarjan(int u)
 40 {
 41     //cout<<u<<endl;
 42     int v ;
 43     vis[u] = 1 ;
 44     dfn[u] = low[u] = ++ timee ;
 45     stk.push(u) ;
 46     for(int i = head[u] ; i != -1 ; i = edge[i].next)
 47     {
 48         v = edge[i].v ;
 49         if(!dfn[v])
 50         {
 51             //printf("v = %d\n",v) ;
 52             tarjan(v) ;
 53             low[u] = min(low[v],low[u]) ;
 54         }
 55         else if(vis[v])
 56             low[u] = min(low[u],dfn[v]) ;
 57     }
 58     if(low[u] == dfn[u])
 59     {
 60         cntt ++ ;
 61         do
 62         {
 63             v = stk.top() ;
 64             stk.pop() ;
 65             vis[v] = 0 ;
 66             belong [v] = cntt ;
 67          //   puts("1") ;
 68         }
 69         while(v != u) ;
 70     }
 71 }
 72 void SPFA(int u,int v)
 73 {
 74     queue<int>Q ;
 75     for(int i = 1 ; i <= cntt ; i++)
 76     {
 77         dis[i] = 999999999 ;
 78         vis[i] = 0 ;
 79     }
 80     dis[u] = 0;
 81     vis[u] = 1;
 82     Q.push(u) ;
 83     while(!Q.empty())
 84     {
 85         int s = Q.front() ;
 86         Q.pop() ;
 87         vis[s] = 0 ;
 88         for(int i = 1 ; i <= n ; i ++ )
 89         {
 90             if(p[s][i] != 999999999)
 91             {
 92                 if(dis[i] > dis[s] + p[s][i])
 93                 {
 94                     dis[i] = dis[s] + p[s][i] ;
 95                     if(!vis[i])
 96                     {
 97                         Q.push(i) ;
 98                         vis[i] = 1 ;
 99                     }
100                 }
101             }
102         }
103     }
104     if(dis[v] != 999999999)
105         printf("%d\n",dis[v]) ;
106     else printf("Nao e possivel entregar a carta\n") ;
107 }
108 void rebuild()
109 {
110     for(int i = 1 ; i <= n ; i++)
111     {
112         for(int j = head[i] ; j != -1 ; j = edge[j].next)
113         {
114          //   int s = edge[i].v ;
115             int v = belong[edge[j].v] ;
116             int u = belong[edge[j].u] ;
117             if(u != v)
118                 p[u][v] = min(p[u][v],edge[j].w) ;
119         }
120     }
121     for(int i = 1 ; i <= cntt ; i++)
122         p[i][i] = 0 ;
123 }
124 int main()
125 {
126     int x,y,h,k;
127     while(~scanf("%d %d",&n,&m))
128     {
129         if(n == 0 && m == 0) break ;
130         Init() ;
131         for(int i = 0 ; i < m ; i++)
132         {
133             scanf("%d %d %d",&x,&y,&h) ;
134             addedge(x,y,h) ;
135         }
136         for(int i = 1 ; i <= n ; i++)
137         {
138             if(!dfn[i])
139                 tarjan(i) ;
140         }
141        // cout<<"s"<<endl;
142         rebuild() ;
143        // cout<<"s"<<endl;
144         scanf("%d",&k) ;
145         for(int i = 0 ; i < k ; i++)
146         {
147             //cout<<i<<endl;
148             scanf("%d %d",&x,&y) ;
149             SPFA(belong[x],belong[y]) ;
150         }
151         printf("\n") ;
152     }
153     return 0 ;
154 }

时间: 2024-10-13 23:35:43

POJ 3114 Countries in War(强联通分量+Tarjan)的相关文章

POJ 3114 Countries in War(强连通分量+最短路)

题目大意: n个间谍 他们之间传送信息需要一定的时间一个联通分量里面的间谍属于一个国家,之间的信息传递不需要时间然后问你从一个间谍传一个信息到另一个间谍那需要最少时间 也可能传不到 思路:先缩点,再最短路,由于n最大只有500.可以用邻接矩阵,而且对缩点后的DAG的边权可以做贪心处理,只留两个强连通分量间的最短边长即可. //2852K 297MS C++ 2595B #include<cstdio> #include<iostream> #include<cstring&g

POJ 3114 Countries in War 强连通+最短路

用floyd超时了...注定的事情...题意:看案例就跑出来了..不需要看题了把.. #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #include<vector> const int INF =1999299; int minn(int a,int b) { return a>b?b:a; } #define N 510 #define M

POJ 3114 Countries in War(强连通+最短路)

POJ 3114 Countries in War 题目链接 题意:给定一个有向图,强连通分支内传送不需要花费,其他有一定花费,每次询问两点的最小花费 思路:强连通缩点后求最短路即可 代码: #include <cstdio> #include <cstring> #include <vector> #include <queue> #include <stack> #include <algorithm> using namespa

POJ 2186 Popular cows(Kosaraju+强联通分量模板)

题目链接:http://poj.org/problem?id=2186 题目大意:给定N头牛和M个有序对(A,B),(A,B)表示A牛认为B牛是红人,该关系具有传递性,如果牛A认为牛B是红人,牛B认为牛C是红人,那么牛A也认为牛C是红人.求被其他所有牛认为是红牛的牛的总数. 解题思路:把所有牛看成顶点,把有序对(A,B)看成从A到B的有向边,那么题目就变成了求所有顶点都可到达的顶点的总数.我们可以得到一个结论,如果一个强连通分量里有一头牛被认为是红人,那么该强联通分量里的所有牛都是红人,这显然是

bzoj 2438: [中山市选2011]杀人游戏 (强联通分量 Tarjan)

Description 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面,查出谁是杀手. 警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他认识的人, 谁是杀手, 谁是平民. 假如查证的对象是杀手, 杀手将会把警察干掉. 现在警察掌握了每一个人认识谁. 每一个人都有可能是杀手,可看作他们是杀手的概率是相同的. 问:根据最优的情况,保证警察自身安全并知道谁是杀手的概率最大是多少? Input 第一行有两个整数 N,M. 接下来有 M 行,每行两个整数 x

POJ 3114 - Countries in War(强连通分量+缩点+拓扑排序+DAG最短路)

Countries in War Time Limit:1000MS    Memory Limit:65536KB    64bit IO Format:%I64d & %I64u Appoint description: Description In the year 2050, after different attempts of the UN to maintain peace in the world, the third world war broke out. The impor

hdu 1269 (强联通分量Tarjan入门)

迷宫城堡 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 10075    Accepted Submission(s): 4529 Problem Description 为 了训练小希的方向感,Gardon建立了一座大城堡,里面有N个房间(N<=10000)和M条通道(M<=100000),每个通道都是单 向的,就是说若称某通道连通

有向图的强联通分量 tarjan

多与DAG上的DP之类的问题一起出现. using namespace std; const int MAXE = 300010; const int MAXP = 100010; struct N { int v,next; }edge[MAXE]; int head[MAXP]; int Top; int ty[MAXP]; int high[MAXP]; int lowlink[MAXP]; int SCCans,dfsclock; int S[MAXP],STop; void InitG

POJ 2186-Popular Cows (图论-强联通分量Korasaju算法)

题目链接:http://poj.org/problem?id=2186 题目大意:有n头牛和m对关系, 每一对关系有两个数(a, b)代表a牛认为b牛是“受欢迎”的,且这种关系具有传递性, 如果a牛认为b牛“受欢迎”, b牛认为c牛“受欢迎”, 那么a牛也认为c牛“受欢迎”. 现在想知道有多少头牛受除他本身外其他所有牛的欢迎? 解题思路:如果有两头或者多头牛受除他本身外其他所有牛的欢迎, 那么在这两头或者多头牛之中, 任意一头牛也受两头或者多头牛中别的牛的欢迎, 即这两头或者多头牛同属于一个强联