hdu 5294 Tricks Device(2015多校第一场第7题)最大流+最短路
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5294
题意:给你n个墓室,m条路径,一个人在1号墓室(起点),另一个人在n号墓室(终点),起点的那个人只有通过最短路径才能追上终点的那个人,而终点的那个人能切断任意路径。
第一问——终点那人要使起点那人不能追上的情况下可以切的最少的路径数,输出最少的路径数
第二问——起点那人能追上终点那人的情况下,终点那人能切断的最多的路径数,输出最多的路径数
思路:要使起点那人无法追上,只要使他的最短路径不存在就好了,那么只要在最短路径上使每条路的流量为1,并球出1-n的最大流就是,能切断的最少的路径数;
要是起点那人能追上,那么只要他的最短路径存在就可以了,并在这些最短路径中求出路径数最少的那条,那么最多的路径数就是m-路径数最少的那条的路径数。
代码:
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cmath> 4 #include <cstring> 5 #include <iostream> 6 #include <queue> 7 #include <algorithm> 8 #include <vector> 9 using namespace std; 10 #define LL __int64 11 #define INF 0x3f3f3f3f 12 const int MAXN=20005; 13 struct qnode 14 { 15 int v; 16 int c; 17 qnode(int _v=0,int _c=0):v(_v),c(_c){} 18 bool operator <(const qnode &r)const 19 { 20 return c>r.c; 21 } 22 }; 23 bool vis[2005]; 24 int dist[2005]; 25 int mp[2005][2005]; 26 void Dijkstra(int n,int start)//求最短路径大小 27 { 28 memset(vis,false,sizeof(vis)); 29 for(int i=1;i<=n;i++)dist[i]=INF; 30 priority_queue<qnode>que; 31 while(!que.empty())que.pop(); 32 dist[start]=0; 33 que.push(qnode(start,0,0)); 34 qnode tmp; 35 while(!que.empty()) 36 { 37 tmp=que.top(); 38 que.pop(); 39 int u=tmp.v; 40 if(vis[u])continue; 41 vis[u]=true; 42 for(int i=1;i<=n;i++) 43 { 44 if(!vis[i]&&mp[u][i]<INF&&dist[i]>dist[u]+mp[u][i]) 45 { 46 dist[i]=dist[u]+mp[u][i]; 47 que.push(qnode(i,dist[i])); 48 } 49 } 50 } 51 } 52 53 int mp2[2005][2005]; 54 void Dijkstra1(int n,int start)//求最短的路数 55 { 56 memset(vis,false,sizeof(vis)); 57 for(int i=1;i<=n;i++)dist[i]=INF; 58 priority_queue<qnode>que; 59 while(!que.empty())que.pop(); 60 dist[start]=0; 61 que.push(qnode(start,0,0)); 62 qnode tmp; 63 while(!que.empty()) 64 { 65 tmp=que.top(); 66 que.pop(); 67 int u=tmp.v; 68 int gg=tmp.flag+1; 69 if(vis[u])continue; 70 vis[u]=true; 71 for(int i=1;i<=n;i++) 72 { 73 if(!vis[i]&&mp2[u][i]<INF&&dist[i]>dist[u]+mp2[u][i]) 74 { 75 dist[i]=dist[u]+mp2[u][i]; 76 que.push(qnode(i,dist[i])); 77 } 78 } 79 } 80 } 81 struct edge 82 { 83 int from,to,cap,flow; 84 edge(){} 85 edge(int f,int t,int c,int fl):from(f),to(t),cap(c),flow(fl){} 86 }; 87 88 struct Dinic 89 { 90 int n,m,s,t; 91 vector<edge> edges; 92 vector<int> G[MAXN]; 93 int cur[MAXN]; 94 int d[MAXN]; 95 bool vis[MAXN]; 96 void init(int n,int s,int t) 97 { 98 this->n=n, this->s=s, this->t=t; 99 edges.clear(); 100 for(int i=0;i<n;i++) G[i].clear(); 101 } 102 void AddEdge(int from,int to,int cap) 103 { 104 edges.push_back( edge(from,to,cap,0) ); 105 edges.push_back( edge(to,from,0,0) ); 106 m = edges.size(); 107 G[from].push_back(m-2); 108 G[to].push_back(m-1); 109 } 110 bool BFS() 111 { 112 queue<int> Q; 113 Q.push(s); 114 memset(vis,0,sizeof(vis)); 115 d[s]=0; 116 vis[s]=true; 117 while(!Q.empty()) 118 { 119 int x=Q.front(); Q.pop(); 120 for(int i=0;i<G[x].size();++i) 121 { 122 edge& e=edges[G[x][i]]; 123 if(!vis[e.to] && e.cap>e.flow) 124 { 125 d[e.to]=1+d[x]; 126 vis[e.to]=true; 127 Q.push(e.to); 128 } 129 } 130 } 131 return vis[t]; 132 } 133 int DFS(int x,int a) 134 { 135 if(x==t || a==0) return a; 136 int flow=0,f; 137 for(int& i=cur[x];i<G[x].size();++i) 138 { 139 edge& e=edges[G[x][i]]; 140 if(d[e.to]==d[x]+1 && (f=DFS(e.to,min(a,e.cap-e.flow) ) )>0) 141 { 142 e.flow +=f; 143 edges[G[x][i]^1].flow -=f; 144 flow +=f; 145 a-=f; 146 if(a==0) break; 147 } 148 } 149 return flow; 150 } 151 int max_flow() 152 { 153 int ans=0; 154 while(BFS()) 155 { 156 memset(cur,0,sizeof(cur)); 157 ans += DFS(s,INF); 158 } 159 return ans; 160 } 161 }DC; 162 int ggg[2005][2005]; 163 164 int main() 165 { 166 int n,m,i,j,a,b,c; 167 while(~scanf("%d%d",&n,&m)) 168 { 169 DC.init(n,1,n); 170 memset(ggg,0,sizeof(ggg)); 171 for(i=1;i<=n;i++) 172 for(j=1;j<=n;j++) 173 mp[i][j]=mp2[i][j]=INF; 174 for(i=0;i<m;i++) 175 { 176 scanf("%d%d%d",&a,&b,&c); 177 if(mp[a][b]>c) 178 { 179 mp[a][b]=c; 180 mp[b][a]=c; 181 ggg[a][b]=1; 182 ggg[b][a]=1; 183 } 184 else if(mp[a][b]==c) 185 { 186 ggg[a][b]++; 187 ggg[b][a]++; 188 } 189 } 190 Dijkstra(n,1); 191 for(i=1;i<=n;i++) 192 { 193 for(j=1;j<=n;j++) 194 { 195 if(mp[i][j]+dist[i]==dist[j]) 196 { 197 for(int k=0;k<ggg[i][j];k++) 198 DC.AddEdge(i,j,1); 199 mp2[i][j]=1; 200 } 201 } 202 } 203 Dijkstra1(n,1); 204 printf("%d %d\n",DC.max_flow(),m-dist[n]); 205 } 206 return 0; 207 }