zoukankan      html  css  js  c++  java
  • 最近水的一些模板题

    KMP: 洛谷P3375
    https://www.luogu.org/problem/show?pid=3375

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    using namespace std;
    const int MAXN = (int)1e6, MAXM = 1000;
    char s1[MAXN + 10], s2[MAXM + 10];
    inline void read(char *str)
    {
        char c;
        int len = 0;
        while(!isgraph(c = getchar()));
        while(isgraph(c))
            str[len++] = c, c = getchar();
    }
    inline void print(int x)
    {
        static int ans[10], top = 0;
        if(x == 0)
            putchar('0');
        while(x)
            ans[top ++] = x % 10, x /= 10;
        while(top)
            putchar(ans[-- top] + '0');
    }
    int pre[MAXN];
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("L3375.in", "r", stdin);
        freopen("L3375.out", "w", stdout);
        #endif
        read(s1), read(s2);
        int len2 = strlen(s2), p = - 1;
        pre[0] = - 1;
        for(int i = 1; i < len2; i ++)
        {
            while(p != - 1 && s2[p + 1] != s2[i])
                p = pre[p];
            p += (s2[p + 1] == s2[i]);
            pre[i] = p;
        }
        int len1 = strlen(s1);
        p = - 1;
        for(int i = 0; i < len1; i ++)
        {
            while(p != - 1 && s1[i] != s2[p + 1])
                p = pre[p];
            p += (s2[p + 1] == s1[i]);
            if(p + 1 == len2)
                print(i - len2 + 2), putchar('
    '), p = pre[p];
        }
        for(int i = 0; i < len2; i ++)
            print(pre[i] + 1), putchar(' ');
    }

    网络流: 洛谷P3376
    https://www.luogu.org/problem/show?pid=3376
    △这里注意一下, 输出优化要特判0和负数的情况

    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<climits>
    #include<algorithm>
    using namespace std;
    inline void read(int &x)
    {
        char c;
        x = 0;
        int flag = 1;
        while(! isgraph(c = getchar()))
            if(c == '-')
                flag *= - 1;
        while(isgraph(c))
            x = x * 10 + c - '0', c = getchar();
        x *= flag;
    }
    const int maxN = (int)1e4, maxM = (int)1e5;
    struct edge
    {
        int v, w, next;
    }G[(maxM << 1) + 64];
    int top;
    int head[maxN + 64];
    inline void addEdge(int u, int v, int w)
    {
        G[top].v = v;
        G[top].w = w;
        G[top].next = head[u];
        head[u] = top ++;
    }
    int Q[maxN + 64];
    int dep[maxN + 64];
    inline int BFS(int s, int t)
    {
        int L = 0, R = 1;
        Q[L] = s;
        memset(dep, - 1, sizeof(dep));
        dep[s] = 0;
        while(L < R)
        {
            int u = Q[L];
            for(int i = head[u]; i != - 1; i = G[i].next)
                if(dep[G[i].v] == - 1 && G[i].w)
                    dep[G[i].v] = dep[u] + 1, Q[R ++] = G[i].v;
            L ++;
        }
        return (dep[t] == - 1) ? 0 : 1;
    }
    inline int DFS(int u, int flow, int t)
    {
        if(u == t)
            return flow;
        int flow_sum = 0;
        for(int i = head[u]; i != - 1; i = G[i].next)
        {
            int v = G[i].v;
            if(G[i].w && dep[v] == dep[u] + 1)
            {
                int cur_flow = min(G[i].w, flow - flow_sum);
                cur_flow = DFS(v, cur_flow, t);
                flow_sum += cur_flow;
                G[i].w -= cur_flow;
                G[i ^ 1].w += cur_flow;
            }
        }
        if(! flow_sum)  //这一句可以优化很多 
            dep[u] = - 1; 
        return flow_sum;
    }
    void print(int x)
    {
        if(x < 0)
            putchar('-'), x *= - 1;
        if(x == 0)
            putchar('0');
        int ans[10], top = 0;
        while(x)
            ans[top ++] = x % 10, x /= 10;
        for(; top; top --)
            putchar(ans[top - 1] + '0');
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("L3376.in", "r", stdin);
        freopen("L3376.out", "w", stdout);
        #endif
        int n, m, s, t;
        read(n), read(m), read(s), read(t);
        memset(head, - 1, sizeof(head));
        top = 0;
        for(int i = 0; i < m; i ++)
        {
            int u, v, w;
            read(u), read(v), read(w);
            addEdge(u, v, w);
            addEdge(v, u, 0);
        }
        int flow = 0;
        while(BFS(s, t))
            while(int tmp = DFS(s, INT_MAX, t))
                flow += tmp;
        print(flow);
    }

    最小费用最大流: 洛谷P3381
    https://www.luogu.org/problem/show?pid=3381

    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<queue>
    #include<climits>
    using namespace std;
    inline void read(int &x)
    {
        char c;
        int flag = 1;
        x = 0;
        while(! isgraph(c = getchar()))
            if(c == '-')
                flag *= - 1;
        while(isgraph(c))
            x = x * 10 + c - '0', c = getchar();
        x *= flag;
    }
    const int MAXN = 5000;
    const int MAXM = (int)5e4;
    int top;
    struct edge
    {
        int v, w, cost, next;
    }G[(MAXM << 1) + 64];
    int head[MAXN + 64];
    inline void addEdge(int u, int v, int w, int cost)
    {
        G[top].v = v;
        G[top].w = w;
        G[top].cost = cost;
        G[top].next = head[u];
        head[u] = top ++;
    }
    int inQ[MAXN + 64], dis[MAXN + 64], pre[MAXN + 64], path[MAXN + 64];
    int SPFA(int s, int t)
    {
        memset(dis, 127, sizeof(dis));
        dis[s] = 0;
        queue<int>Q;
        Q.push(s);
        memset(inQ, 0, sizeof(inQ));
        inQ[s] = 1;
        memset(pre, - 1, sizeof(pre));
        while(! Q.empty())
        {
            int u = Q.front();
            Q.pop();
            for(int i = head[u]; i != - 1; i = G[i].next)
            {
                int v = G[i].v;
                if(G[i].w == 0 || dis[v] <= dis[u] + G[i].cost)
                    continue;
                dis[v] = dis[u] + G[i].cost;
                pre[v] = u;
                path[v] = i;
                if(! inQ[v])
                    Q.push(v), inQ[v] = 1;
            }
            inQ[u] = 0;
        }
        if(pre[t] == - 1)
            return 0;
        return 1;
    }
    int max_flow = 0;
    int end(int s, int t)
    {
        int flow = INT_MAX, ret = 0;
        for(int i = t; i != s; i = pre[i])
            flow = min(flow, G[path[i]].w);
        max_flow += flow;
        for(int i = t; i != s; i = pre[i])
            G[path[i]].w -= flow,
            G[path[i] ^ 1].w += flow,
            ret += flow * G[path[i]].cost;
        return ret;
    }
    void print(int x)
    {
        int ans[10], top = 0;
        if(x == 0)
            putchar('0');
        while(x)
            ans[top ++] = x % 10, x /= 10;
        for(; top; top --)
            putchar(ans[top - 1] + '0');
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("L3381.in", "r", stdin);
        freopen("L3381.out", "w", stdout);
        #endif
        int n, m, s, t;
        read(n), read(m), read(s), read(t);
        memset(head, - 1, sizeof(head));
        top = 0;
        for(int i = 0; i < m; i ++)
        {
            int u, v, w, cost;
            read(u), read(v), read(w), read(cost);
            addEdge(u, v, w, cost);
            addEdge(v, u, 0, - cost);
        }
        int cost = 0;
        while(SPFA(s, t))
            cost += end(s, t);
        print(max_flow), putchar(' '), print(cost);
    }

    二分图最大匹配: 洛谷P3386
    https://www.luogu.org/problem/show?pid=3386

    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<queue>
    #include<climits>
    #include<algorithm>
    using namespace std;
    void read(int &x)
    {
        char c;
        int flag = 1;
        x = 0;
        while(! isgraph(c = getchar()))
            if(c == '-')
                flag *= - 1;
        while(isgraph(c))
            x = x * 10 + c - '0', c = getchar();
        x *= flag;
    }
    const int MAXN = 1000, MAXM = 1000;
    const int MAXE = MAXN * MAXM;
    int head[MAXN + MAXM + 64];
    int top;
    struct edge
    {
        int v, w,next;
    }G[(MAXE << 1) + (MAXN << 1) + (MAXM << 1) + 64];
    void add_edge(int u, int v, int w)
    {
        G[top].v = v;
        G[top].w = w;
        G[top].next = head[u];
        head[u] = top ++;
    }
    int dis[MAXN + MAXM + 64];
    int BFS(int s, int t)
    {
        queue<int>Q;
        Q.push(s);
        memset(dis, - 1, sizeof(dis));
        dis[s] = 0;
        while(! Q.empty())
        {
            int u = Q.front();
            Q.pop();
            for(int i = head[u]; i != - 1; i = G[i].next)
                if(G[i].w && dis[G[i].v] == - 1)
                    Q.push(G[i].v), dis[G[i].v] = dis[u] + 1;
        }
        return (dis[t] == - 1) ? 0 : 1;
    }
    int DFS(int u, int flow ,int t)
    {
        if(u == t)
            return flow;
        int max_flow = 0;
        for(int i = head[u]; i != - 1; i = G[i].next)
        {
            int v = G[i].v;
            if(G[i].w && dis[v] == dis[u] + 1)
            {
                int cur_flow = min(flow - max_flow, G[i].w);
                cur_flow = DFS(v, cur_flow, t);
                G[i].w -= cur_flow;
                G[i ^ 1].w += cur_flow;
                max_flow += cur_flow;
            }
        }
        if(! max_flow)
            dis[u] = - 1;
        return max_flow;
    }
    void print(int x)
    {
        if(x < 0)
            putchar('-'), x *= - 1;
        if(x == 0)
            putchar('0');
        int ans[10], top = 0;
        while(x)
            ans[top ++] = x % 10, x /= 10;
        for(; top; top --)
            putchar(ans[top - 1] + '0');
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("L3386.in", "r", stdin);
        freopen("L3386.out", "w", stdout);
        #endif
        int n, m, e;
        read(n), read(m), read(e);
        memset(head, - 1, sizeof(head));
        top = 0;
        for(int i = 0; i < e; i ++)
        {
            int u, v;
            read(u), read(v);
            add_edge(u, n + v, 1);
            add_edge(n + v, u, 0);
        }
        for(int i = 1; i <= n; i ++)
            add_edge(0, i, 1), add_edge(i, 0, 0);
        for(int i = n + 1; i <= n + m; i ++)
            add_edge(i, n + m + 1, 1), add_edge(n + m + 1, i, 0);
        int flow = 0;
        while(BFS(0, n + m + 1))
            while(int del = DFS(0, INT_MAX, n + m + 1))
                flow += del;
        print(flow);
    }

    割点: 洛谷P3388
    https://www.luogu.org/problem/show?pid=3388

    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<algorithm>
    #include<deque>
    using namespace std;
    int n, m;
    void read(int &x)
    {
        char c;
        int flag = 1;
        x = 0;
        while(! isgraph(c = getchar()))
            if(c == '-')
                flag *= - 1;
        while(isgraph(c))
            x = x * 10 + c - '0', c = getchar();
        x *= flag;
    }
    const int MAXN = (int)1e5;
    const int MAXM = (int)1e5;
    int top;
    struct edge
    {
        int v, next;
    }G[(MAXM << 1) + 64];
    int head[MAXN + 64];
    void add_edge(int u, int v)
    {
        G[top].v = v;
        G[top].next = head[u];
        head[u] = top ++;
    }
    int iscut[MAXN + 64];
    int dfn[MAXN + 64], low[MAXN + 64];
    deque<int>Q;
    int vis[MAXN + 64];
    int tarjan(int u, int fa)
    {
        vis[u] = 1;
        Q.push_back(u);
        low[u] = dfn[u] = dfn[fa] + 1;
        int cnt = 0;
        for(int i = head[u]; i != - 1; i = G[i].next)
        {
            int v = G[i].v;
            if(v == fa)
                continue;
            if(dfn[v] == - 1)
            {
                cnt ++;
                low[u] = min(tarjan(v, u), low[u]);
                if(low[v] >= dfn[u])
                    iscut[u] = 1;
            }
            else
                low[u] = min(dfn[v], low[u]);
        }
        if(low[u] == dfn[u])
        {
            if(Q.front() == u && cnt < 2)   //注意: 对于根节点, 要特判 
                iscut[u] = 0;
            while(Q.back() != u)
                Q.pop_back();
            Q.pop_back();
        }
        return low[u];
    }
    void print(int x)
    {
        if(x < 0)
            putchar('-'), x *= - 1;
        if(x == 0)
            putchar('0');
        int ans[10], top = 0;
        while(x)
            ans[top ++] = x % 10, x /= 10;
        for(; top; top --)
            putchar(ans[top - 1] + '0');
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("L3388.in", "r", stdin);
        freopen("L3388.out", "w", stdout);
        #endif
        read(n), read(m);
        top = 0;
        memset(head, - 1, sizeof(head));
        for(int i = 0; i < m; i ++)
        {
            int u, v;
            read(u), read(v);
            add_edge(u, v);
            add_edge(v, u);
        }
        memset(iscut, 0, sizeof(iscut));
        memset(dfn, - 1, sizeof(dfn));
        memset(vis, 0, sizeof(vis));
        for(int i = 1; i <= n; i ++)
            if(! vis[i])
                tarjan(i, i);
        int cnt = 0;
        for(int i = 1; i <= n ; i ++)
            if(iscut[i])
                cnt ++;
        print(cnt);
        putchar('
    ');
        for(int i = 1; i <= n; i ++)
            if(iscut[i])
                print(i), putchar(' ');
    }
  • 相关阅读:
    如何提交docker镜像到DockerHub
    【leetcode】200. Number of Islands
    【Java NIO】一文了解NIO
    【Java】同步阻塞式(BIO)TCP通信
    【剑指offer】9、斐波拉契数列
    SolidWorks242个使用技巧
    BR(BoomerangRobot)机器人项目
    Android学习笔记基于回调的事件处理
    Android学习笔记基于监听的事件处理
    Android学习笔记Log类输出日志信息
  • 原文地址:https://www.cnblogs.com/ZeonfaiHo/p/6402842.html
Copyright © 2011-2022 走看看