大体题意:
给你一个有向图,告诉你起点S和终点T,要求找出不同的路径来,满足路径是最短路,并且每个路只能用一次!
思路:
方法很巧妙:
可以转换到最大流
先正着求一边单源最短路,在倒着求一边,把在最短路上的边加入到网络中,权值为1,直接求最大流即可!(想一想就知道!)
判断是否在最短路也很简单:
直接看这个边的一个点到S的最短距离和另一个点到T的最短距离之和 加上权值 如果是最短路的话,那么这个边肯定在最短路中了!反之不再!
第一次做 结果超时了 用dinic算法即可!(好水= = )
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 1000 + 10;
///max flow=====================================
struct Edge{
int from, to, cap, flow;
Edge(int from = 0,int to = 0 ,int cap = 0, int flow = 0):from(from),to(to),cap(cap),flow(flow){}
};
struct Dinic{
int n, m ,s, t;
vector<Edge> edges;
vector<int> G[maxn];
bool vis[maxn];
int d[maxn];
int cur[maxn];
void init(int n){
this->n = n;
for (int i = 0; i <= n; ++i){
G[i].clear();
}
edges.clear();
}
void AddEdge(int from,int to, int cap){
edges.push_back(Edge(from, to, cap, 0));
edges.push_back(Edge(to,from,0,0));
m = edges.size();
G[from].push_back(m-2);
G[to].push_back(m-1);
}
bool BFS(){
memset(vis,0,sizeof vis);
queue<int> Q;
Q.push(s);
d[s] = 0;
vis[s] = 1;
while(!Q.empty()){
int x = Q.front(); Q.pop();
for (int i = 0; i < G[x].size(); ++i){
Edge& e = edges[G[x][i]];
if (!vis[e.to] && e.cap > e.flow){
vis[e.to] = 1;
d[e.to] = d[x] + 1;
Q.push(e.to);
}
}
}
return vis[t];
}
int DFS(int x,int a){
if (x == t || a == 0) return a;
int flow = 0, f;
for (int& i = cur[x]; i < G[x].size(); ++i){
Edge& e = edges[G[x][i]];
if (d[x] + 1 == d[e.to] && (f = DFS(e.to,min(a,e.cap-e.flow))) > 0){
e.flow += f;
edges[G[x][i]^1].flow -= f;
flow += f;
a-=f;
if (!a)break;
}
}
return flow;
}
int MaxFlow(int s,int t){
this->s = s; this->t = t;
int flow = 0;
while(BFS()){
memset(cur,0,sizeof cur);
flow += DFS(s,inf);
}
return flow;
}
}mmf;
///=========================================
/// ====== Dijkstra
struct Edge2{
int from, to, dist;
Edge2(int from = 0,int to = 0,int dist = 0):from(from),to(to),dist(dist){}
};
struct HeapNode{
int d, u;
HeapNode(int d = 0,int u = 0):d(d),u(u){}
bool operator < (const HeapNode& rhs) const {
return d > rhs.d;
}
};
struct Dijkstra{
int n, m ;
vector<Edge2> edges;
vector<int> G[maxn];
bool done[maxn];
int d[maxn];
int p[maxn];
void init(int n){
this->n = n;
for (int i = 1; i <= n; ++i) G[i].clear();
edges.clear();
}
void AddEdge(int from,int to,int dist){
edges.push_back(Edge2(from,to,dist));
m = edges.size();
G[from].push_back(m-1);
}
void dijkstra(int s){
priority_queue<HeapNode> Q;
for (int i = 1; i <= n; ++i) d[i] = inf;
d[s] = 0;
memset(done,0,sizeof done);
Q.push(HeapNode(0,s));
while(!Q.empty()){
HeapNode x = Q.top(); Q.pop();
int u = x.u;
if (done[u])continue;
done[u] = 1;
for (int i = 0; i < G[u].size(); ++i){
Edge2& e = edges[G[u][i]];
if (d[e.to] > d[u] + e.dist){
d[e.to] = d[u] + e.dist;
p[e.to] = G[u][i];
Q.push(HeapNode(d[e.to],e.to));
}
}
}
}
}dijs,dijt;
///==============================================
int main(){
int T;
scanf("%d",&T);
while(T--){
int n, m;
scanf("%d %d",&n,&m);
dijs.init(n);
dijt.init(n);
mmf.init(n);
for (int i = 0; i < m; ++i){
int u, v, w;
scanf("%d %d %d",&u, &v, &w);
dijs.AddEdge(u,v,w);
dijt.AddEdge(v,u,w);
}
int s,t;
scanf("%d %d",&s,&t);
dijs.dijkstra(s);
dijt.dijkstra(t);
int len = dijs.edges.size();
for (int i = 0; i < len; ++i){
int u = dijs.edges[i].from;
int v = dijs.edges[i].to;
int w = dijs.edges[i].dist;
if (dijs.d[u] + dijt.d[v] + w == dijs.d[t]){
mmf.AddEdge(u,v,1);
}
}
if (dijs.d[t] == inf){
printf("0\n");
continue;
}
int ans = mmf.MaxFlow(s,t);
printf("%d\n",ans);
}
return 0;
}
Description
Do not sincere non-interference。
Like that show, now starvae also take part in a show, but it take place between city A and B. Starvae is in city A and girls are in city B. Every time starvae can get to city B and make a data with a girl he likes. But there are two problems with it, one is starvae must get to B within least time, it's said that he must take a shortest path. Other is no road can be taken more than once. While the city starvae passed away can been taken more than once. So, under a good RP, starvae may have many chances to get to city B. But he don't know how many chances at most he can make a data with the girl he likes . Could you help starvae? Input
The first line is an integer T indicating the case number.(1<=T<=65)
For each case,there are two integer n and m in the first line ( 2<=n<=1000, 0<=m<=100000 ) ,n is the number of the city and m is the number of the roads. Then follows m line ,each line have three integers a,b,c,(1<=a,b<=n,0<c<=1000)it means there is a road from a to b and it's distance is c, while there may have no road from b to a. There may have a road from a to a,but you can ignore it. If there are two roads from a to b, they are different. At last is a line with two integer A and B(1<=A,B<=N,A!=B), means the number of city A and city B. There may be some blank line between each case. Output
Output a line with a integer, means the chances starvae can get at most.
Sample Input 3 7 8 1 2 1 1 3 1 2 4 1 3 4 1 4 5 1 4 6 1 5 7 1 6 7 1 1 7 6 7 1 2 1 2 3 1 1 3 3 3 4 1 3 5 1 4 6 1 5 6 1 1 6 2 2 1 2 1 1 2 2 1 2 Sample Output 2 1 1 Source | ![]() |
Problem descriptions:
![]() |