POJ 3114 Countries in War 强连通+dijkstra .

来源:互联网 发布:视频边框软件是什么 编辑:程序博客网 时间:2024/06/09 16:25

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


0 0
原创粉丝点击