题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3599
思路:首先spfa求一下最短路,然后对于满足最短路上的边(dist[v]==dist[u]+w)加入到新图中来,边容量为1,最后求出的最大流就是没有相交的边的最短路径条数。
1 #include<iostream> 2 #include<cstdio> 3 #include<string> 4 #include<algorithm> 5 #include<vector> 6 #include<queue> 7 using namespace std; 8 #define MAXN 4444 9 #define inf 1<<30 10 11 struct Node{ 12 int v,w; 13 Node(int vv,int ww):v(vv),w(ww){}; 14 }; 15 16 int n; 17 bool mark[MAXN]; 18 int dist[MAXN]; 19 vector<vector<Node> >G; 20 void spfa() 21 { 22 memset(mark,false,sizeof(mark)); 23 fill(dist,dist+n+2,inf); 24 dist[1]=0; 25 queue<int>que; 26 que.push(1); 27 while(!que.empty()){ 28 int u=que.front(); 29 que.pop(); 30 mark[u]=false; 31 for(int i=0;i<G[u].size();i++){ 32 int v=G[u][i].v; 33 int w=G[u][i].w; 34 if(dist[u]+w<dist[v]){ 35 dist[v]=dist[u]+w; 36 if(!mark[v]){ 37 mark[v]=true; 38 que.push(v); 39 } 40 } 41 } 42 } 43 } 44 45 struct Edge{ 46 int v,cap,next; 47 }edge[MAXN*MAXN]; 48 49 int NE,NV; 50 int head[MAXN]; 51 52 void Insert(int u,int v,int cap) 53 { 54 edge[NE].v=v; 55 edge[NE].cap=cap; 56 edge[NE].next=head[u]; 57 head[u]=NE++; 58 59 edge[NE].v=u; 60 edge[NE].cap=0; 61 edge[NE].next=head[v]; 62 head[v]=NE++; 63 } 64 65 void Build() 66 { 67 NE=0; 68 NV=n; 69 memset(head,-1,sizeof(head)); 70 for(int u=1;u<=n;u++){ 71 for(int i=0;i<G[u].size();i++){ 72 int v=G[u][i].v,w=G[u][i].w; 73 if(dist[u]+w==dist[v]){ 74 Insert(u,v,1); 75 } 76 } 77 } 78 } 79 80 int level[MAXN],gap[MAXN]; 81 void bfs(int vt) 82 { 83 memset(level,-1,sizeof(level)); 84 memset(gap,0,sizeof(gap)); 85 queue<int>que; 86 que.push(vt); 87 level[vt]=0; 88 gap[level[vt]]++; 89 while(!que.empty()){ 90 int u=que.front(); 91 que.pop(); 92 for(int i=head[u];i!=-1;i=edge[i].next){ 93 int v=edge[i].v; 94 if(level[v]!=-1)continue; 95 level[v]=level[u]+1; 96 gap[level[v]]++; 97 que.push(v); 98 } 99 } 100 } 101 102 int pre[MAXN],cur[MAXN]; 103 int SAP(int vs,int vt) 104 { 105 bfs(vt); 106 memset(pre,-1,sizeof(pre)); 107 memcpy(cur,head,sizeof(head)); 108 int u=pre[vs]=vs,aug=inf,maxflow=0; 109 gap[0]=NV; 110 while(level[vs]<NV){ 111 bool flag=false; 112 for(int &i=cur[u];i!=-1;i=edge[i].next){ 113 int v=edge[i].v; 114 if(edge[i].cap>0&&level[u]==level[v]+1){ 115 flag=true; 116 aug=min(aug,edge[i].cap); 117 pre[v]=u; 118 u=v; 119 if(v==vt){ 120 maxflow+=aug; 121 for(u=pre[v];v!=vs;v=u,u=pre[u]){ 122 edge[cur[u]].cap-=aug; 123 edge[cur[u]^1].cap+=aug; 124 } 125 aug=inf; 126 } 127 break; 128 } 129 } 130 if(flag)continue; 131 int minlevel=NV; 132 for(int i=head[u];i!=-1;i=edge[i].next){ 133 int v=edge[i].v; 134 if(edge[i].cap>0&&level[v]<minlevel){ 135 minlevel=level[v]; 136 cur[u]=i; 137 } 138 } 139 if(--gap[level[u]]==0)break; 140 level[u]=minlevel+1; 141 gap[level[u]]++; 142 u=pre[u]; 143 } 144 return maxflow; 145 } 146 147 148 int main() 149 { 150 int _case,u,v,w; 151 scanf("%d",&_case); 152 while(_case--){ 153 scanf("%d",&n); 154 G.clear(); 155 G.resize(n+2); 156 while(true){ 157 scanf("%d%d%d",&u,&v,&w); 158 if(u==0&&v==0&&w==0)break; 159 G[u].push_back(Node(v,w)); 160 G[v].push_back(Node(u,w)); 161 } 162 spfa(); 163 if(dist[n]==inf||n==1){ 164 puts("0"); 165 continue; 166 } 167 Build(); 168 printf("%d ",SAP(1,n)); 169 } 170 return 0; 171 }