HDU 3416 - Shortest path + Maximum current

Posted by lancia on Tue, 30 Jul 2019 04:07:48 +0200

Topic link: http://acm.hdu.edu.cn/showproblem.php?pid=3416

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

Don't interfere sincerely. A kind of
I like that program. Now the stars also participate in a program, but it happens between city A and B. Starvae in City A and Girls in City B. Every time Starvae arrives at City B, it does data with the girls he likes. But there are two problems. One is that Xinghua must arrive at B in the shortest time. It is said that he must take the shortest road. The other is that no road can be taken more than once. And City Star can die more than once. A kind of
Therefore, under a good RP, Starvae may have many chances to get to City B. A kind of
‎ ‎
But he didn't know how many chances he had. He could do the most data with the girl he liked. Can you help starva? A kind of

Input

The first line is the integer T representing the case number. (1<_T< #65)*
For each case, there are two integers n and m in the first line (2 < n_lt; 1000, 0_lt; m_lt; 100000) which are the number of cities and the number of roads. A kind of
Then follow the m line, each line has three integers a, b, c, (1_lt; _a, b_lt; n, 0_lt; c_lt; _lt; _lt; _lt; _1000) indicating that there is a path from a to b, the distance from B to a may not be.
Road. There may be a way from one road to another, but you can ignore it. If there are two paths from a to b, they are different. Finally, there is a line containing two integers A and B (1_lt; A, B_lt; _N, A!= B), representing the city A
* and the number of city B. There may be some blank lines between each case. A kind of
‎ ‎

Output

Output of an integer line means that the star can only get the most opportunities.

 

In fact, the meaning of the question is to let you find several shortest paths.

First, we need to know a theorem that if an edge is the shortest one, then dis[e.from]+e.dis=dis[e.to];

After that, it was very good and classical.

First, run a shortest path and find the edge satisfying dis[e.from]+e.dis=dis[e.to], that is, the edge on the shortest path.

Then the maximum flow edge is constructed on each shortest path with a capacity of 1, and the maximum flow is obtained as a result.

However, the shortest path is implemented by DIjkstra algorithm based on minimum heap, and SPFA will be timed out.

#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=1e5+7;
const int maxm=1e5+7;
struct Edge{
    int from,to;
    LL val;
};
struct HeapNode{
    LL d;           
    int u;
    bool operator < (const HeapNode & rhs) const{
		return d > rhs.d;
	}  
};
struct Dijstra{
    int n,m;
    vector<Edge> edges;
    vector<int> G[maxn];
    bool used[maxn];
    LL d[maxn];
    int p[maxn];

    void init(int n){
        this->n = n;
        for(int i=0;i<=n;++i)    G[i].clear();
        edges.clear();
        memset(used,0,sizeof(used));
    }

    void Addedge(int from,int to ,LL dist){
        edges.push_back((Edge){from,to,dist});
        m = edges.size();
        G[from].push_back(m-1);
    }

    void dijkstra(int s){   
        priority_queue<HeapNode> Q;
        for(int i=0;i<=n;++i)    d[i]=INF;
        d[s]=0;
        Q.push((HeapNode){0,s});
        while(!Q.empty()){
            HeapNode x =Q.top();Q.pop();
            int u =x.u;
            if(used[u]) 
                continue;
            used[u]= true;
            for(int i=0;i<G[u].size();++i){
                Edge & e = edges[G[u][i]];
                if(d[e.to] > d[u] + e.val){
                    d[e.to] = d[u] +e.val;
                    p[e.to] = G[u][i];
                    Q.push((HeapNode){d[e.to],e.to});
                }
            }
        }
    }
}Dijk;
const int MAXN=1010;
const int MAXM=200010;
struct Node{
    int from,to,next;
    int cap;
};
struct SAP_MaxFlow{
    int n,m;        
    int tol;
    int head[MAXN];
    int dep[MAXN];
    int gap[MAXN];
    Node edge[MAXM];

    void init(int N){
        this->n = N;
        this->tol=0;
        memset(head,-1,sizeof(head));
    }

    void AddEdge(int u,int v,int w){
        edge[tol].from=u;edge[tol].to=v;edge[tol].cap=w;edge[tol].next=head[u];head[u]=tol++;
        edge[tol].from=v;edge[tol].to=u;edge[tol].cap=0;edge[tol].next=head[v];head[v]=tol++;
    }

    void BFS(int start,int end)
    {
        memset(dep,-1,sizeof(dep));
        memset(gap,0,sizeof(gap));
        gap[0]=1;
        int que[MAXN];
        int front,rear;
        front=rear=0;
        dep[end]=0;
        que[rear++]=end;
        while(front!=rear){
            int u=que[front++];
            if(front==MAXN)front=0;
            for(int i=head[u];i!=-1;i=edge[i].next){
                int v=edge[i].to;
                if(dep[v]!=-1)continue;
                que[rear++]=v;
                if(rear==MAXN)rear=0;
                dep[v]=dep[u]+1;
                ++gap[dep[v]];
            }
        }
    }
    int SAP(int start,int end)
    {
        int res=0;
        BFS(start,end);
        int cur[MAXN];
        int S[MAXN];
        int top=0;
        memcpy(cur,head,sizeof(head));
        int u=start;
        int i;
        while(dep[start]<n){
            if(u==end){
                int temp=INF;
                int inser;
                for(i=0;i<top;i++)
                   if(temp>edge[S[i]].cap){
                       temp=edge[S[i]].cap;
                       inser=i;
                   }
                for(i=0;i<top;i++){
                    edge[S[i]].cap-=temp;
                    edge[S[i]^1].cap+=temp;
                }
                res+=temp;
                top=inser;
                u=edge[S[top]].from;
            }
            if(u!=end&&gap[dep[u]-1]==0)//Faults, no augmented Road
              break;
            for(i=cur[u];i!=-1;i=edge[i].next)
               if(edge[i].cap!=0&&dep[u]==dep[edge[i].to]+1)
                 break;
            if(i!=-1){
                cur[u]=i;
                S[top++]=i;
                u=edge[i].to;
            }
            else{
                int min=n;
                for(i=head[u];i!=-1;i=edge[i].next){
                    if(edge[i].cap==0)continue;
                    if(min>dep[edge[i].to]){
                        min=dep[edge[i].to];
                        cur[u]=i;
                    }
                }
                --gap[dep[u]];
                dep[u]=min+1;
                ++gap[dep[u]];
                if(u!=start)u=edge[S[--top]].from;
            }
        }
        return res;
    }
}sap;
int n,m,s,t;
int main(){
	int T;
	scanf("%d",&T);
	while(T--){
		scanf("%d%d",&n,&m);
		Dijk.init(n);
		sap.init(n);
		for(int i = 0;i<m;++i){
			int u,v,w;
			scanf("%d%d%d",&u,&v,&w);
			Dijk.Addedge(u,v,w);
		}
		scanf("%d%d",&s,&t);
		Dijk.dijkstra(s);
		for(int i = 0;i<m;++i){
			Edge e=Dijk.edges[i];
			if(Dijk.d[e.from]+e.val==Dijk.d[e.to]){
				sap.AddEdge(e.from,e.to,1);
			}
		} 
		printf("%d\n",sap.SAP(s,t));
	}
	return 0;
} 

 

Topics: PHP