https://vjudge.net/problem/HDU-3416
题意:给出一个图,有多少个边不重复的最短路。
思路:先用dijkstar从s跑最短路,然后再从t倒着跑一边(注意该题是有向图,我一开始当成无向图了......),从而通过d1[u[i]]+d2[v[i]]+c[i]=d1[t]确定哪一条边属于最短路,然后把属于最短路的边建图跑最大流,每条边的容量为1。
#include<bits/stdc++.h> #define _for(i,a,b) for(int i=a;i<=b;i++) using namespace std; typedef long long ll; const int mod =1e6+7; double esp=1e-6; int INF =0x3f3f3f3f; //const int inf = 1<<28; const int MAXN=200000+10; const int inf=0x3f3f3f3f; using namespace std; typedef long long LL; int n,m,u[MAXN],v[MAXN],c[MAXN]; ll dis1[MAXN],dis2[MAXN]; struct node { ll d,x; bool operator <(const node &p)const { return d>p.d; } }; typedef pair<int,int> P; vector <P> GG[MAXN]; priority_queue<node> Q; bool vis[MAXN]; void dijkstar(int s,ll* d1) { memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++)d1[i]=INF; d1[s]=0; Q.push((node){0,s}); while(!Q.empty()) { node tmp=Q.top(); Q.pop(); int u=tmp.x; if(vis[u])continue; vis[u]=1; for(int i=0;i<GG[u].size();i++) { int v=GG[u][i].first; int w=GG[u][i].second; if(d1[v]>d1[u]+w) { d1[v]=d1[u]+w; //printf("%d %d ",v,d[v]); Q.push((node){d1[v],v}); } } } return ; } struct edge { int from,to,cap,flow; }; vector<edge> edges; vector<int> G[MAXN]; void add(int from,int to,int cap) { edges.push_back((edge){from,to,cap,0}); edges.push_back((edge){to,from,0,0}); int m=edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } bool vis1[MAXN]; int cur[MAXN]; int d[MAXN],s,t; bool bfs() { memset(vis1,0,sizeof(vis1)); queue<int>QQ; QQ.push(s); vis1[s]=1; while(!QQ.empty()) { int x=QQ.front(); QQ.pop(); for(int i=0;i<G[x].size();i++) { edge &e=edges[G[x][i]]; if(!vis1[e.to]&&e.cap>e.flow) { vis1[e.to]=1; d[e.to]=d[x]+1; QQ.push(e.to); } } } return vis1[t]; } int dfs(int x,int a) { if(x==t||a==0) return a; int flow=0,f; for(int& i=cur[x];i<G[x].size();i++) { edge &e=edges[G[x][i]]; if(d[x]+1==d[e.to]&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0) { e.flow+=f; edges[G[x][i]^1].flow-=f; flow+=f; a-=f; if(a==0)break; } } return flow; } int max_Flow(int s,int t) { int flow=0; while(bfs()) { //printf("** "); memset(cur,0,sizeof(cur)); flow+=dfs(s,INF); } return flow; } int main() { int T; scanf("%d",&T); { while(T--) { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { scanf("%d%d%d",&u[i],&v[i],&c[i]); GG[u[i]].push_back(P(v[i],c[i])); } scanf("%d%d",&s,&t); dijkstar(s,dis1); //while(!Q.empty())Q.pop(); for(int i=1;i<=n;i++)GG[i].clear(); for(int i=1;i<=m;i++)GG[v[i]].push_back(P(u[i],c[i])); dijkstar(t,dis2); //for(int i=1;i<=n;i++)printf("%lld %lld ",dis1[i],dis2[i]); for(int i=1;i<=m;i++) { if(dis1[u[i]]+c[i]+dis2[v[i]]==dis1[t]) { add(u[i],v[i],1); //printf("%d %d ",u[i],v[i]); } } cout<<max_Flow(s,t)<<endl; for(int i=1;i<=n;i++) { G[i].clear(); GG[i].clear(); } } } return 0; }