Codeforces Round #165 (Div. 1)--C. Flawed Flow--類拓撲

C. Flawed Flow

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Emuskald considers himself a master of flow algorithms. Now he has completed his most ingenious program yet — it calculates the maximum flow in an undirected graph. The graph consists of n vertices and m edges. Vertices are numbered from 1 to n. Vertices 1 and nbeing the source and the sink respectively.

However, his max-flow algorithm seems to have a little flaw — it only finds the flow volume for each edge, but not its direction. Help him find for each edge the direction of the flow through this edges. Note, that the resulting flow should be correct maximum flow.

More formally. You are given an undirected graph. For each it's undirected edge (aibi) you are given the flow volume ci. You should direct all edges in such way that the following conditions hold:

  1. for each vertex v (1 < v < n), sum of ci of incoming edges is equal to the sum of ci of outcoming edges;
  2. vertex with number 1 has no incoming edges;
  3. the obtained directed graph does not have cycles.

Input

The first line of input contains two space-separated integers n and m (2 ≤ n ≤ 2·105, n - 1 ≤ m ≤ 2·105), the number of vertices and edges in the graph. The following m lines contain three space-separated integers aibi and ci (1 ≤ ai, bi ≤ nai ≠ bi, 1 ≤ ci ≤ 104), which means that there is an undirected edge from ai to bi with flow volume ci.

It is guaranteed that there are no two edges connecting the same vertices; the given graph is connected; a solution always exists.

Output

Output m lines, each containing one integer di, which should be 0 if the direction of the i-th edge is ai → bi (the flow goes from vertex ai to vertex bi) and should be 1 otherwise. The edges are numbered from 1 to m in the order they are given in the input.

If there are several solutions you can print any of them.

Examples

input

Copy

3 3
3 2 10
1 2 10
3 1 5

output

Copy

1
0
1

input

Copy

4 5
1 2 10
1 3 10
2 3 5
4 2 15
3 4 5

output

Copy

0
0
1
1
0

Note 

In the first test case, 10 flow units pass through path , and 5 flow units pass directly from source to sink: .

 

給出一個圖(無向圖)的各個邊的流量,讓確定各個邊的方向,使得1<i<n,每個點的入流量=出流量。

1號節點無入邊,圖中無環。

思路:讓每一個點入度=出度,先統計每個點的流量,讓其/2,然後不斷使其入流量添加,使其讓他=出流量。

參考:https://blog.csdn.net/mengxiang000000/article/details/78164922

#include <algorithm>    //STL通用算法
#include <bitset>     //STL位集容器
#include <cmath>
#include <cstdio>
#include <cstring>
#include <deque>      //STL雙端隊列容器
#include <exception>    //異常處理類
#include <fstream>
#include <functional>   //STL定義運算函數(代替運算符)
#include <limits>
#include <list>      //STL線性列表容器
#include <map>       //STL 映射容器
#include <iomanip>
#include <ios>      //基本輸入/輸出支持
#include<iosfwd>     //輸入/輸出系統使用的前置聲明
#include <iostream>
#include <istream>     //基本輸入流
#include <ostream>     //基本輸出流
#include <queue>      //STL隊列容器
#include <set>       //STL 集合容器
#include <sstream>    //基於字符串的流
#include <stack>      //STL堆棧容器    
#include <string>     //字符串類
#include <vector>     //STL動態數組容器
#define ll long long
using namespace std;
#define rep(i,a,b) for(register int i=(a);i<=(b);i++)
#define dep(i,a,b) for(register int i=(a);i>=(b);i--)
//priority_queue<int,vector<int>,less<int> >q;
int dx[]= {-1,1,0,0,-1,-1,1,1};
int dy[]= {0,0,-1,1,-1,1,1,-1};
const int maxn = 1000000+66;
const int maxm=1500000+66;
const ll mod=1e9+7;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
const int INF=99999999;
struct node
{
    int from,to;
    int next;
    int w;
    int dir;
    int id;
} edge[maxn];
int head[maxn];
int in[maxn];
int out[maxn];
int ans[maxn];
int n,m,cnt;
void add(int from,int to,int w,int dir,int id)
{
    edge[cnt].from=from;
    edge[cnt].to=to;
    edge[cnt].w=w;
    edge[cnt].dir=dir;
    edge[cnt].id=id;
    edge[cnt].next=head[from];
    head[from]=cnt++;
}
void  Tui()
{
    queue<int>q;
    q.push(1);
    in[1]=out[1]=0;
    while(q.size())
    {
        int u=q.front();
        q.pop();
        for(int i=head[u]; i!=-1; i=edge[i].next)
        {
            int v=edge[i].to;
            int w=edge[i].w;
            int dir=edge[i].dir;
            if(v==1)
                continue;
            if(in[v]==out[v]&&v!=n)
                continue;
            if(u==1||v==n)
            {
                if(u==1)
                {
                    ans[edge[i].id]=dir;
                    in[v]+=w;
                }
                else
                {
                    ans[edge[i].id]=dir;
                }
            }
            else
            {
                if(in[v]<out[v])
                {
                    in[v]+=w;
                    ans[edge[i].id]=dir;
                }
                else
                {
                    ans[edge[i].id]=1-dir;
                }
            }
            if(in[v]==out[v]&&v!=n)
            {
                q.push(v);
            }
        }
    }
    rep(i,1,m)
    {
        printf("%d\n",ans[i]);
    }
    return ;
}
int main()
{
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        cnt=0;
        rep(i,1,maxn-1)
        {
            in[i]=0;
            out[i]=0;
            head[i]=-1;
        }
        rep(i,1,m)
        {
            int u,v,w;
            scanf("%d %d %d",&u,&v,&w);
            add(u,v,w,0,i);
            add(v,u,w,1,i);
            out[u]+=w;
            out[v]+=w;
        }
        rep(i,1,n)
        {
            out[i]=out[i]/2;
        }
        Tui();
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章