题目地址: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 stack
low[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;
}