[AHOI2006] 上学路线 route
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1266
分析:
第一问是朴素的最短路,因为数据小,Floyd也可(但我还是写了Dijkstra)
然后是第二问:大意就是,在这个图的“最短路图”(即将等长的边也加入最短路树,就成了一个”最短路图”)上,找一个最小割,容量即删除的代价,直接最大流跑过。
建图时注意细节。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#define rep(i,x,y) for (int i=x;i<=y;i++)
#define dep(i,y,x) for (int i=y;i>=x;i--)
using namespace std;
const int maxn=1000+23,INF=(1<<29);
//Dijkstra的边
struct dEdge{ 
  int to,dist,c;
  dEdge(int x,int y,int z):to(x),dist(y),c(z) {}
};
//Dinic的边
struct Edge{ 
  int from,to,flow,cap;
  Edge(int x,int y,int z,int p):from(x),to(y),flow(z),cap(p) {}
};
struct cmp{
  bool operator() (const dEdge a,const dEdge b) const {
   return a.dist>b.dist;
  }
};
int n,m,p,q,t,c,d[maxn],cur[maxn];
vector<dEdge> G[maxn]; //最短路邻接表
vector<int> a[maxn]; //网络流邻接表
vector<Edge> E;
bool vis[maxn];
void Dijkstra() //最短路
{
 memset(vis,0,sizeof(vis));
 d[1]=0;rep(i,2,n) d[i]=INF;
 priority_queue<dEdge,vector<dEdge>,cmp> Q;
 
 Q.push(dEdge(1,0,0));
 while (!Q.empty())
 {
  dEdge x=Q.top(); Q.pop();
  if (vis[x.to]) continue; 
  vis[x.to]=1; d[x.to]=x.dist;
  int len=G[x.to].size();
  rep(i,0,len-1)
  {
   dEdge S=G[x.to][i];
   if ((d[x.to]+S.dist)<d[S.to])
   {
    d[S.to]=d[x.to]+S.dist;
    Q.push(dEdge(S.to,d[S.to],0));
   }
  }
 }
}
void addEdge(int u,int v,int c) //网络流建边
{
 E.push_back(Edge(u,v,0,c));
 E.push_back(Edge(v,u,0,0));
 int M=E.size();
 a[u].push_back(M-2);
 a[v].push_back(M-1);
}
void Graph_DFS(int k) //网络流建图,从终点向起点DFS
{
 if (vis[k]) return; else vis[k]=1;
 int len=G[k].size();
 rep(i,0,len-1)
 {
  dEdge x=G[k][i];
  if ((d[x.to]+x.dist)==d[k])
  {
   addEdge(x.to,k,x.c);
   Graph_DFS(x.to);
  }
 }
}
// ---------Dinic---------
bool BFS()
{
 memset(vis,0,sizeof(vis));
 queue<int> Q;
 Q.push(1); vis[1]=1;
 d[1]=0;
 while (!Q.empty())
 {
  int x=Q.front(),len=a[x].size();Q.pop();
  rep(i,0,len-1)
  {
   Edge& Eg=E[a[x][i]];
   if ((Eg.cap>Eg.flow) && (!vis[Eg.to]))
   {
    vis[Eg.to]=1;
    Q.push(Eg.to);
    d[Eg.to]=d[x]+1;
   }
  }
 }
 return vis[n]; 
}
int DFS(int x,int Fl)
{
 if ((x==n) || (Fl==0)) return Fl;
 int flow=0,f,len=a[x].size();
 for (int& i=cur[x];i<len;i++)
 {
  Edge& Ed=E[a[x][i]];
  if ((d[Ed.to]==(d[x]+1)) && (f=DFS(Ed.to,min(Fl,Ed.cap-Ed.flow))))
  {
   Ed.flow+=f;
   E[a[x][i]^1].flow-=f;
   flow+=f;
   Fl-=f;
   if (Fl==0) break;
  }
 }
 return flow;
}
int Maxflow()
{
 int ans=0;
 while (BFS())
 {
  memset(cur,0,sizeof(cur));
  ans+=DFS(1,INF);
 }
 return ans;
}
int main()
{
 scanf("%d%d",&n,&m);
 rep(i,1,m)
 {
  scanf("%d%d%d%d",&p,&q,&t,&c);
  G[p].push_back(dEdge(q,t,c));
  G[q].push_back(dEdge(p,t,c)); 
 }
 Dijkstra();
 printf("%d\n",d[n]);
 memset(vis,0,sizeof(vis));
 Graph_DFS(n);
 printf("%d\n",Maxflow());
 
 return 0;
}
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号