记录编号 366884 评测结果 AAAAAAAAAAAAAAAAAAAAAAAAA
题目名称 [HZOI 2016]颓废元 最终得分 100
用户昵称 Gravatarztx 是否通过 通过
代码语言 C++ 运行时间 0.033 s
提交时间 2017-01-26 12:23:01 内存使用 0.44 MiB
显示代码纯文本
/***
 * ans1 ope 1 x边是否一定在最大流的边集中,重设x边两端点为S,T推流是否能推尽
 * ans2 ope 2 x边是否在所有最小割边集中,残量网络 dfs求S,T点集,x边两侧属于不同点集则在所有最小割边集中
 * ans3 最大流
 * ans4 字典序最小的最小割边集:
 * 从小到大枚举割边,并计算没有这条边的最大流,如最大流减少,则删去此边,记下此时的最大流,答案中加上此边;否则,不删边,枚举下一条边;直到最后最大流变为0.
 *
 */

#include <bits/stdc++.h>

int CH , NEG ;
template<typename TP>inline void read(TP& ret) {
    ret = NEG = 0 ; while (CH=getchar() , CH<'!') ;
    if (CH == '-') NEG = true , CH = getchar() ;
    while (ret = ret*10+CH-'0' , CH=getchar() , CH>'!') ;
    if (NEG) ret = -ret ;
}

#define Rep(i,l,r) for(i=(l);i<=(r);i++)
#define rep(i,l,r) for(i=(l);i< (r);i++)
#define Rev(i,r,l) for(i=(r);i>=(l);i--)
#define rev(i,r,l) for(i=(r);i> (l);i--)
#define  maxN  410LL
#define  maxM  4010LL
#define  infi  0x3f3f3f3fLL
#define  s(u)  star[u]
#define  t(p)  e[0][p]
#define  n(p)  e[1][p]
#define  f(p)  e[2][p]
#define  r(x)  read(x)

int e[3][maxM<<1], star[maxN] , tote = 1;
inline void AddEdge(int u, int v, int cap) {
    tote ++ , t(tote) = v, f(tote) = cap, n(tote) = s(u), s(u) = tote;
    tote ++ , t(tote) = u, f(tote) = 0, n(tote) = s(v), s(v) = tote;
}

#define  min(x,y) ((x)<(y)?(x):(y))
int N, S, T, h[maxN], vh[maxN];

int dfs(int u , int flowu) {
int p, tmp = h[u]+1, flow = 0, flowv;
    if (u == T) return flowu;
    for (p = s(u); p; p = n(p))
        if (f(p) && (h[t(p)]+1==h[u])) {
            flowv = dfs(t(p),min(flowu-flow,f(p)));
            flow += flowv, f(p) -= flowv, f(p^1) += flowv;
            if (flow==flowu || h[S]==N) return flow;
        }
    for (p = s(u); p; p = n(p))
        if (f(p)) tmp = min(tmp,h[t(p)]);
    if (--vh[h[u]] == 0) h[S] = N;
    else ++ vh[h[u]=tmp+1];
    return flow;
}

int SAP() {
    int ret = 0;
    memset(vh, 0, sizeof vh);
    memset(h, 0, sizeof h);
    vh[S] = N;
    while (h[S] < N) ret += dfs(S,infi);
    return ret;
}

int vis[maxN] = {0};
void dfs2(int u,int i) {
    vis[u] = i+1;
    for (int p = s(u); p; p = n(p))
        if (!vis[t(p)] && f(p^i)) dfs2(t(p),i) ;
}


int n, m;
int x[maxM], y[maxM], poi[maxM];
bool ans2[maxM] = {0};

std::vector<int>ans4_0, ans4_1;
std::vector<int>::iterator it;

inline void Judge() {
int i , u , v , p ;
    dfs2(S,0) ;
    dfs2(T,1) ;
    Rep (i,1,m) {
        u = x[i];
        v = y[i];
        if (!f(poi[i]) && vis[u] && vis[v] && vis[u]!=vis[v])
            ans2[i] = true, ans4_0.push_back(i);
        else if (!f(poi[i]) && (!vis[u] || !vis[v])) //  modify 01
            ans4_1.push_back(i);
    }
// puts("printing   ans4_0");
// for (it = ans4_0.begin(); it != ans4_0.end(); it ++ )
//     printf("%d ", *it);
// puts("printing   ans4_1");
// for (it = ans4_1.begin(); it != ans4_1.end(); it ++ )
//     printf("%d ", *it);
// puts("\nendit-----------");
}

inline void ans1(int i) {
    if (f(poi[i])) {
        puts("0"); return;
    }
    int u = x[i] , v = y[i];
    if ((vis[u] || vis[v]) && (vis[u] != vis[v])) {puts("1"); return;}
    if (!vis[u] && !vis[v]) puts("1");
    else puts("0");


    return;

// printf("answering %d: ", i);
    if (f(poi[i]^1) == 0) { puts("0"); return; }
    int rec1 = f(poi[i]), rec2 = f(poi[i]^1), rflow = 0;
    f(poi[i]) = f(poi[i]^1) = 0;
    S = x[i], T = y[i];
    memset(vh, 0, sizeof vh);
    memset(h, 0, sizeof h);
    vh[S] = N;
    while (h[S]<N && rflow<rec2) rflow += dfs(S,rec2-rflow);
    f(poi[i]) = rec1+rflow, f(poi[i]^1) = rec2-rflow;
// printf(" ==================> rflow = %d rec2 = %d\n", rflow, rec2);
    printf("%d\n", rflow!=rec2);
}

inline void F5() {
    int i;
    Rep (i,1,m) f(poi[i]) += f(poi[i]^1), f(poi[i]^1) = 0;
}

inline void ans4() {
    int last, now, rec;
    F5();
    for (it = ans4_0.begin(); it != ans4_0.end(); it ++ )
        f(poi[*it]) = 0;
    S = 1, T = n;
    last = SAP(); F5();
    for (it = ans4_1.begin(); it != ans4_1.end(); it ++ ) {
        if (last == 0) break;
        rec = f(poi[*it]), f(poi[*it]) = 0;
        now = SAP(); F5();
        if (now == last) f(poi[*it]) = rec;
        else last = now, ans4_0.push_back(*it);
    }
    std::sort(ans4_0.begin(), ans4_0.end());
    for (it = ans4_0.begin(); it != ans4_0.end(); it ++ )
        printf("%d ", *it);
}

inline void Print() {
puts("printing ===============");
    for (int i = 2; i < tote; i += 2) {
        printf("%d  ->  %d :  %d  %d \n", t(i+1), t(i), f(i), f(i+1));
    }
puts("end printing ===========");
}


int main() {
  #define READ
    #ifdef  READ
        freopen("JJandLazy.in" ,"r",stdin ) ;
        freopen("JJandLazy.out","w",stdout) ;
    #endif
    int i, ans3, q, ope;
    r(n), r(m);
    N = n, S = 1, T = n;
    Rep (i,1,m) {
        r(x[i]), r(y[i]), r(q);
        poi[i] = tote+1;
        AddEdge(x[i],y[i],q);
    }
    ans3 = SAP(); // t3
// Print();
    Judge();  // t2 & select edges for ans4
    for (r(q); q; q -- ) {
        r(ope), r(i);
        if (ope == 1) 
// Print(),
            ans1(i);
        //if (ope == 2) printf("%d\n", ans2[i]);

        else printf("%d\n", ans2[i]);
    }
    printf("%d\n", ans3);
// puts("ans4-------------");
    ans4();
    #ifdef  READ
        fclose(stdin) ; fclose(stdout) ;
    #else
        getchar() ; getchar() ;
    #endif
    return 0 ;
}

/*
7
7
1 2 10
2 3 1
3 4 1
4 7 10
1 5 10
5 6 1
6 7 10
5
1 2
1 3
1 6
2 6
2 2


you 0 you 1
*/