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

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-lyslyslys

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值