当前位置: 代码迷 >> 综合 >> POJ 3114 Countries in War 强连通+dijkstra .
  详细解决方案

POJ 3114 Countries in War 强连通+dijkstra .

热度:92   发布时间:2023-09-23 07:42:54.0

题目地址:http://poj.org/problem?id=3114

缩点再用dijkstra查找一下就好了

#include<iostream>
#include<cstdio>
#include<vector>
#include<stack> 
#include<queue> 
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=500+10;
const int INF=1000000000;
typedef pair<int,int> pii;
struct Edge{int to,weight;Edge(int t,int w):to(t),weight(w){}
};
bool vis[maxn];
int ID[maxn];    //点的颜色编号 
int index,ncolor;      
vector<int> dfn(maxn),low(maxn),st;
vector<vector<int> > color(maxn); //同一种颜色的点 
vector<vector<Edge> > G(maxn),NG(maxn);  
void Tarjan(int u)
{dfn[u]=low[u]=++index;vis[u]=true;st.push_back(u);for(int i=0;i<G[u].size();i++){int v=G[u][i].to;if(!vis[v]){Tarjan(v);low[u]=min(low[u],low[v]);}else if(find(st.begin(),st.end(),v)!=st.end()) //in stacklow[u]=min(low[u],dfn[v]);}if(dfn[u]==low[u]){int v; ncolor++;do{v=st.back(); st.pop_back();color[ncolor].push_back(v);ID[v]=ncolor;}while(v!=u);}
}
int getGraph(int n)
{index=ncolor=0; st.clear();memset(vis,false,sizeof(vis));for(int i=1;i<=n;i++)if(!vis[i]) Tarjan(i);for(int i=1;i<=ncolor;i++)  //缩点,建新图 {for(int j=0;j<color[i].size();j++){int u=color[i][j];for(int k=0;k<G[u].size();k++){int v=G[u][k].to, w=G[u][k].weight;if(ID[u]==ID[v]) 	NG[u].push_back(Edge(v,0));else NG[u].push_back(Edge(v,w));}}}
}
bool done[maxn];
int dist[maxn];
bool Dijkstra(int s,int t,int n)
{priority_queue<pii,vector<pii>,greater<pii> > Q;fill(dist,dist+n+1,INF);                //初始化为无穷大 memset(done,false,sizeof(done));dist[s]=0;Q.push(pii(0,s));      //pii (dist ,u)while(!Q.empty()){int u=Q.top().second; Q.pop();if(done[u]) continue;     //可改为if(dist[u]!=Q.top().first) continue; done[u]=true;            if(u==t) return dist[u]!=INF;for(int i=0;i<NG[u].size();i++){Edge& e=NG[u][i];int v=e.to ,w=e.weight;if(done[v]) continue;if(dist[v]>dist[u]+w){dist[v]=dist[u]+w;Q.push(pii(dist[v],v));}}}return false;
}int main()
{int n,m,k,u,v,w;while(scanf("%d%d",&n,&m)){if(n==0&&m==0) break;for(int i=1;i<=n;i++) G[i].clear(),color[i].clear(),NG[i].clear();while(m--){scanf("%d%d%d",&u,&v,&w);G[u].push_back(Edge(v,w));}getGraph(n);scanf("%d",&k);while(k--){scanf("%d%d",&u,&v);if(Dijkstra(u,v,n)) cout<<dist[v]<<endl;else cout<<"Nao e possivel entregar a carta"<<endl;}cout<<endl;}return 0;
}