Path HDU - 6582 最短路+最小割-阻塞最短路

Years later, Jerry fell in love with a girl, and he often walks for a long time to pay visits to her. But, because he spends too much time with his girlfriend, Tom feels neglected and wants to prevent him from visiting her.
After doing some research on the neighbourhood, Tom found that the neighbourhood consists of exactly nn houses, and some of them are connected with directed road. To visit his girlfriend, Jerry needs to start from his house indexed 11 and go along the shortest path to hers, indexed nn.
Now Tom wants to block some of the roads so that Jerry has to walk longer to reach his girl's home, and he found that the cost of blocking a road equals to its length. Now he wants to know the minimum total cost to make Jerry walk longer.
Note, if Jerry can't reach his girl's house in the very beginning, the answer is obviously zero. And you don't need to guarantee that there still exists a way from Jerry's house to his girl's after blocking some edges.

Input

The input begins with a line containing one integer T(1≤T≤10)T(1≤T≤10), the number of test cases.
Each test case starts with a line containing two numbers n,m(1≤n,m≤10000)n,m(1≤n,m≤10000), the number of houses and the number of one-way roads in the neighbourhood.
mm lines follow, each of which consists of three integers x,y,c(1≤x,y≤n,1≤c≤109)x,y,c(1≤x,y≤n,1≤c≤109), denoting that there exists a one-way road from the house indexed xx to yy of length cc.

Output

Print TT lines, each line containing a integer, the answer.

Sample Input

1
3 4
1 2 1
2 3 1
1 3 2
1 3 3

Sample Output

3

题意:就是给你m条边n个点让这个图的1-n的最短路不再是最短路的花费

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
const int maxn = 1009;
struct Edge{
	int from, to, cap, flow;
	Edge(){}
	Edge(int from, int to, int cap, int flow):from(from), to(to), cap(cap), flow(flow){}	
};
struct Dinic{
	int n, m, s, t;
	vector<Edge>edges;
	vector<int>G[maxn];
	int d[maxn];
	int cur[maxn];
	int vis[maxn];
	void init(int n, int s, int t)
	{
		this->n = n;this->s = s;this->t = t;
		edges.clear();
		for(int i = 0;i <= n;++i) G[i].clear();
	}
	void add_edge(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] = true;
		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] = true;
					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 == 0)break; 
			}
		}
		return flow;
	}
	int maxflow()
	{
		int flow = 0;
		while(bfs())
		{
			memset(cur, 0, sizeof(cur));
			flow += dfs(s,inf);
		}
		return flow;
	}
}solve;//刘汝佳网络流dinic板子
struct Edge1
{
    int from, to; ll dist;       //起点,终点,距离
    Edge1(int from, int to, ll dist):from(from), to(to), dist(dist) {}
};
int n,m; 
struct Dijkstra
{
    int n, m;                 //结点数,边数(包括反向弧)
    vector<Edge1> edges;       //边表。edges[e]和edges[e^1]互为反向弧
    vector<int> G[maxn];      //邻接表,G[i][j]表示结点i的第j条边在edges数组中的序号
    int vis[maxn];            //标记数组
    ll d[maxn];              //s到各个点的最短路
    int p[maxn];              //上一条弧
 
    void init(int n)
    {
        this->n = n;
        edges.clear();
        for (int i = 0; i <= n; i++) G[i].clear();
    }
 
    void AddEdge(int from, int to, int dist)
    {
        edges.push_back(Edge1(from, to, dist));
        m = edges.size();
        G[from].push_back(m - 1);
    }
 
    struct HeapNode
    {
        int from; ll dist;
        bool operator < (const HeapNode& rhs) const
        {
            return rhs.dist < dist;
        }
        HeapNode(int u, ll w): from(u), dist(w) {}
    };
 
    void dijkstra(int s)
    {
        priority_queue<HeapNode> Q;
        for (int i = 0; i <= n; i++) d[i] = inf;
        memset(vis, 0, sizeof(vis));
        d[s] = 0;
        Q.push(HeapNode(s, 0));
        while (!Q.empty())
        {
            HeapNode x = Q.top(); Q.pop();
            int u = x.from;
            if (vis[u]) continue;
            vis[u] = true;
            for (int i = 0; i < G[u].size(); i++)
            {
                Edge1& 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(e.to, d[e.to]));
                }
            }
        }
    }
//    void output(int x)
//    {
//        if (x == 1)
//        {
//            printf("%d", x);
//            return ; 
//        }
//        output(edges[p[x]].from);
//        printf(" %d", x);
//        putchar('\n');
//    }
}gao1, gao2;
struct node{
	int from, to, dist;
}edgeall[100009];
int main()
{
	int t;
	scanf("%d", &t);
	while(t--) {	
		scanf("%d%d", &n, &m);
		gao1.init(n);gao2.init(n);
		int cn = 0;
		for(int i = 1;i <= m;++i) {
			int x, y, step;
			scanf("%d%d%d", &x, &y, &step);
			gao1.AddEdge(x, y, step);
			gao2.AddEdge(y, x, step);
			edgeall[cn].from = x;
			edgeall[cn].to = y;
			edgeall[cn].dist = step;
			cn++; 	
		}
		int start, end;
		scanf("%d%d", &start, &end);
		gao1.dijkstra(start);
		ll  ans = gao1.d[end];
		gao2.dijkstra(end);
		solve.init(n, start, end);
		for(int i = 0;i < m;++i) {
			if(gao1.d[edgeall[i].from] + edgeall[i].dist + gao2.d[edgeall[i].to] == ans) {
				solve.add_edge(edgeall[i].from, edgeall[i].to, 1);
			}
		}
		ll anss = solve.maxflow();
		printf("%lld\n", anss);
	}
	return 0;
}
发布了219 篇原创文章 · 获赞 43 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/qq_43568078/article/details/103337886