[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;
}

posted @ 2016-04-09 22:01  Krew  阅读(163)  评论(0)    收藏  举报