标签:
http://acm.hdu.edu.cn/showproblem.php?pid=5294
8 9 1 2 2 2 3 2 2 4 1 3 5 3 4 5 4 5 8 1 1 6 2 6 7 5 7 8 1
2 6
/** hdu5294 最短路+最大流 题目大意:给定一个无向图,从起点到终点,只有走最短路,才能在规定时限内到达,问最少去掉几条边使不能到达,最多去掉几条边仍能到达 解题思路:http://blog.sina.com.cn/s/blog_15139f1a10102vnx5.html 和官方题解想的一样 */ #include<cstdio> #include<iostream> #include<queue> #include<string.h> using namespace std; const int oo=1e9; const int mm=161111; const int mn=2330; int node,src,dest,edge; int ver[mm],flow[mm],_next[mm]; int head[mn],work[mn],dis[mn],q[mn]; void prepare(int _node,int _src,int _dest) { node=_node,src=_src,dest=_dest; for(int i=0; i<=node; ++i)head[i]=-1; edge=0; } void addedge(int u,int v,int c) { ver[edge]=v,flow[edge]=c,_next[edge]=head[u],head[u]=edge++; ver[edge]=u,flow[edge]=0,_next[edge]=head[v],head[v]=edge++; } bool Dinic_bfs() { int i,u,v,l,r=0; for(i=0; i<node; ++i)dis[i]=-1; dis[q[r++]=src]=0; for(l=0; l<r; ++l) for(i=head[u=q[l]]; i>=0; i=_next[i]) if(flow[i]&&dis[v=ver[i]]<0) { dis[q[r++]=v]=dis[u]+1; if(v==dest)return 1; } return 0; } int Dinic_dfs(int u,int exp) { if(u==dest)return exp; for(int &i=work[u],v,tmp; i>=0; i=_next[i]) if(flow[i]&&dis[v=ver[i]]==dis[u]+1&&(tmp=Dinic_dfs(v,min(exp,flow[i])))>0) { flow[i]-=tmp; flow[i^1]+=tmp; return tmp; } return 0; } int Dinic_flow() { int i,ret=0,delta; while(Dinic_bfs()) { for(i=0; i<node; ++i)work[i]=head[i]; while(delta=Dinic_dfs(src,oo))ret+=delta; } return ret; } ///================================================== const int INF=0x3f3f3f3f; const int maxm=511111; const int maxn=2111; struct EdgeNode { int to; int w; int next; }; EdgeNode edges[maxm]; int N,M; int head1[maxn],edge1; bool vis[maxn]; queue <int> que; int dis1[maxn],dis2[maxn]; void addedge1(int u,int v,int c) { edges[edge1].w=c,edges[edge1].to=v,edges[edge1].next=head1[u],head1[u]=edge1++; } void init() { memset(head1,-1,sizeof(head1)); edge1=0; } void spfa(int s,int n)//单源最短路(s为起点,n为节点总数) { int u; for (int i=0; i<=n; i++) dis1[i]=INF; memset(vis,0,sizeof(vis)); while (!que.empty()) que.pop(); que.push(s); vis[s]=true; dis1[s]=0; while (!que.empty()) { u=que.front(); que.pop(); vis[u]=false; for (int i=head1[u]; i!=-1; i=edges[i].next) { int v=edges[i].to; int w=edges[i].w; if (dis1[v]>dis1[u]+w) { dis1[v]=dis1[u]+w; if (!vis[v]) { vis[v]=true; que.push(v); } } } } } ////======================================== int aa[60080][3],bb[60080][3]; int main() { int n,m; while(~scanf("%d%d",&n,&m)) { init(); for(int i=0;i<m;i++) { scanf("%d%d%d",&aa[i][0],&aa[i][1],&aa[i][2]); addedge1(aa[i][0],aa[i][1],aa[i][2]); addedge1(aa[i][1],aa[i][0],aa[i][2]); } spfa(1,n); memcpy(dis2,dis1,sizeof(dis1)); //printf("dis2->%d\n",dis2[n]); spfa(n,n); // printf("dis1->%d\n",dis1[1]); int k=0; for(int i=0;i<m;i++) { if(dis2[aa[i][0]]>dis2[aa[i][1]]) swap(aa[i][0],aa[i][1]); // printf("n-%d:%d-1 %d %d %d\n",aa[i][1],aa[i][0],dis1[aa[i][1]],aa[i][2],dis2[aa[i][0]]); if(dis1[aa[i][1]]+aa[i][2]+dis2[aa[i][0]]==dis2[n]) { bb[k][0]=aa[i][0]; bb[k++][1]=aa[i][1]; // printf("%d %d\n",bb[k-1][0],bb[k-1][1]); } } prepare(n+1,1,n); for(int i=0;i<k;i++) { addedge(bb[i][0],bb[i][1],1); } int ans1=Dinic_flow(); init(); for(int i=0;i<k;i++) { addedge1(bb[i][0],bb[i][1],1); addedge1(bb[i][1],bb[i][0],1); } spfa(1,n); //printf("%d\n",dis2[n]); int ans2=m-dis1[n]; printf("%d %d\n",ans1,ans2); } return 0; }
8 9 1 2 2 2 3 2 2 4 1 3 5 3 4 5 4 5 8 1 1 6 2 6 7 5 7 8 1
2 6
版权声明:本文为博主原创文章,未经博主允许不得转载。
hdu5294||2015多校联合第一场1007 最短路+最大流
标签:
原文地址:http://blog.csdn.net/lvshubao1314/article/details/46992109