2017 ICPC 乌鲁木齐

H:题目看错 背锅

#include <bits/stdc++.h>
#include <vector>
#define PI acos(-1.0)
#define mem(a,b) memset((a),b,sizeof(a))
#define TS printf("!!!\n")
#define pb push_back
//std::ios::sync_with_stdio(false);
using namespace std;
//priority_queue<int,vector<int>,greater<int>> que;
const double EPS = 1.0e-9;
typedef pair<int, int> pairint;
typedef long long ll;
typedef unsigned long long ull;
const int  maxn = 1e4 + 10;
const int  maxm = 300;
vector<pair<int, int> > p[10005];
int visit[maxn];
int ans[maxn];
int anser = 0;
void dfs(int cur)
{
    int len = p[cur].size();
    if (len == 0)
    {
        ans[cur] = 0;
    }
    for (int i = 0; i < len; i++)
    {
        int to = p[cur][i].first;
        int lenth = p[cur][i].second;
        if (ans[to] != -1)
        {
            ans[cur] = max(ans[cur], ans[to] + lenth);
        }
        else
        {
            dfs(to);
            ans[cur] = max(ans[cur], ans[to] + lenth);
        }
    }
}
int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        anser = 0;
        mem(visit, 0);
        mem(ans, -1);
        int n, m;
        int from, to, lenth;
        cin >> n >> m;
        for (int i = 1; i <= m; i++)
        {
            scanf("%d %d %d", &from, &to, &lenth);
            visit[to] = 1;
            p[from].pb(make_pair(to, lenth));
        }
        for (int i = 1; i <= n; i++)
        {
            if (visit[i] == 0)
            {
                //cout<<i<<endl;
                dfs(i);
                anser = max(anser, ans[i]);
            }
        }
        cout << anser << endl;
        for (int i = 1; i <= n; i++)
        {
            p[i].clear();
        }
    }
}

G:每个test 后面没换行 背锅

#include <bits/stdc++.h>
#include <vector>
#define PI acos(-1.0)
#define mem(a,b) memset((a),b,sizeof(a))
#define TS printf("!!!\n")
#define pb push_back
//std::ios::sync_with_stdio(false);
using namespace std;
//priority_queue<int,vector<int>,greater<int>> que;
const double EPS = 1.0e-9;
typedef pair<int, int> pairint;
typedef long long ll;
typedef unsigned long long ull;
const int  maxn = 1e5 + 10;
const int  maxm = 300;
int n, m, i, num[100001], tree[200001], l, r;
char s[maxn], t[maxn];
int slen, tlen, lencha;
string ch, ch1;
int lowbit(int x)
{
        return x & (-x);
}
void update(int x, int p)
{
        while (x <= n)
        {
                tree[x] += p;
                x += lowbit(x);
        }
        return;
}
int sum(int k)
{
        int ans = 0;
        while (k > 0)
        {
                ans += tree[k];
                k -= lowbit(k);
        }
        return ans;
}
int ask(int l, int r)
{
        return sum(r) - sum(l - 1);
}
int main()
{
        /*cin>>n>>m;
        for(i=1;i<=n;i++)
        {
            cin>>num[i];
            update(i,num[i]);
        }
        for(i=1;i<=m;i++)
        {
            cin>>l>>r;
            cout<<ask(l,r)<<endl;
        }*/
        int time;
        cin >> time;
        while (time--)
        {
                //mem(num, 0);
                mem(tree, 0);
                int now;
                scanf("%d",&m);
                scanf("%s", s + 1);
                scanf("%s", t);
                slen = strlen(s + 1);
                tlen = strlen(t);
                //cout<<slen<<" "<<tlen<<endl;
                lencha = slen - tlen + 1;
                n = slen;
                for (int i = 1; i <= lencha; i++)
                {
                        for (int j = 0; j <= tlen; j++)
                        {
                                if (j == tlen)
                                {
                                        num[i] = 1;
                                        update(i, num[i]);
                                        break;
                                }
                                if (s[i + j] != t[j])
                                {
                                        num[i] = 0;
                                        update(i, num[i]);
                                        break;
                                }

                        }
                }
                /*for (int i = 1; i <= slen; i++)
                {
                        cout << num[i] << " ";
                }
                cout << endl;*/
                for (int i = 1; i <= m; i++)
                {
                        cin >> ch;
                        if (ch[0] == 'Q')
                        {
                                scanf("%d %d", &l, &r);
                                printf("%d\n", ask(l, r - tlen + 1));
                        }
                        else if (ch[0] == 'C')
                        {
                                int flag = 0;
                                scanf("%d", &now);
                                cin >> ch1;
                                if (s[now] != ch1[0])
                                {
                                        flag = 1;
                                }
                                s[now] = ch1[0];
                                int from = max(1, now - tlen + 1);
                                int to = min(lencha, now);
                                if (flag)
                                {
                                        for (int j = from; j <= to; j++)
                                        {
                                                if (num[j] == 1)
                                                {
                                                        num[j] = 0;
                                                        update(j, -1);
                                                }
                                                else
                                                {
                                                        for (int k = 0; k <= tlen; k++)
                                                        {
                                                                if (k == tlen)
                                                                {
                                                                        num[j] = 1;
                                                                        update(j, 1);
                                                                        break;
                                                                }
                                                                if (s[j + k] != t[k])
                                                                {
                                                                        break;
                                                                }
                                                        }
                                                }
                                        }
                                }
                                /*for (int i = 1; i <= slen; i++)
                                {
                                        cout << num[i] << " ";
                                }
                                cout << endl;*/
                        }
                }
                puts("");
        }
        return 0;
}

 J!!!!!!:最小费用最大流

每个城市拆成出点和入点,源点连西安和大连,汇点连上海,相当于求从西安到上海和从大连到上海最小距离之和,每个城市入点和出点之间连一条容量为1的边,但是注意,上海的容量必须是2,再根据给出的边,分别连接出点入点,存入相应花费,那么问题就可以转化成最小费用最大流了,如果流量不为2输出-1,否则输出最小花费。

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<map>
#include<queue>
#include<string>
using namespace std;
#define ll long long
const ll maxm = 10005;
const ll INF = 1e18 + 7;
struct node
{
    ll u, v, flow, cost, next;
}edge[maxm * 10];
map<string, ll>p;
ll cnt, s, t, n, m, sum, FLOW;
ll head[maxm * 10], dis[maxm * 10], pre[maxm * 10];
char a[maxm], b[maxm];
void init()
{
    p.clear();
    cnt = 0, s = 0, t = n * 5 + 1, sum = 0, FLOW = 0;
    memset(head, -1, sizeof(head));
}
void add(ll u, ll v, ll flow, ll cost)
{
    edge[cnt].u = u, edge[cnt].v = v;
    edge[cnt].flow = flow, edge[cnt].cost = cost;
    edge[cnt].next = head[u], head[u] = cnt++;
    edge[cnt].u = v, edge[cnt].v = u;
    edge[cnt].flow = 0, edge[cnt].cost = -cost;
    edge[cnt].next = head[v], head[v] = cnt++;
}
ll bfs()
{
    queue<ll>q;
    for (ll i = 0;i <= t;i++) dis[i] = INF;
    memset(pre, -1, sizeof(pre));
    dis[s] = 0, q.push(s);
    ll rev = 0;
    while (!q.empty())
    {
        ll u = q.front();q.pop();
        for (ll i = head[u];i != -1;i = edge[i].next)
        {
            ll v = edge[i].v;
            if (dis[v] > dis[u] + edge[i].cost&&edge[i].flow)
            {
                dis[v] = dis[u] + edge[i].cost;
                pre[v] = i, q.push(v);
            }
        }
    }
    if (dis[t] == INF) return 0;
    return 1;
}
ll MCMF()
{
    ll ans = 0, minflow;
    while (bfs())
    {
        minflow = INF;
        for (ll i = pre[t];i != -1;i = pre[edge[i].u])
            minflow = min(minflow, edge[i].flow);
        for (ll i = pre[t];i != -1;i = pre[edge[i].u])
            edge[i].flow -= minflow, edge[i ^ 1].flow += minflow;
        ans += dis[t] * minflow;
        FLOW += minflow;
    }
    return ans;
}
int main()
{
    ll i, j, k, T, c;
    scanf("%lld", &T);
    while (T--)
    {
        scanf("%lld", &n);
        init();
        ll nn = n * 2;
        for (i = 1;i <= n;i++)
        {
            scanf("%s%s%lld", a, b, &c);
            if (p[a] == 0)
            {
                p[a] = ++sum, k = 1;
                if (strcmp(a, "Shanghai") == 0) k = 2;
                add(p[a], p[a] + nn, k, 0);
            }
            if (p[b] == 0)
            {
                p[b] = ++sum, k = 1;
                if (strcmp(b, "Shanghai") == 0) k = 2;
                add(p[b], p[b] + nn, k, 0);
            }
            ll u = p[a], v = p[b];
            add(u + nn, v, INF, c);
            add(v + nn, u, INF, c);
        }
        ll u = p["Dalian"];
        add(s, u, 1, 0);
        u = p["Xian"];
        add(s, u, 1, 0);
        u = p["Shanghai"];
        add(u + nn, t, 2, 0);
        ll ans = MCMF();
        if (FLOW == 2) printf("%lld\n", ans);
        else printf("-1\n");
    }
    return 0;
}
View Code

 

posted @ 2017-09-09 20:28  Aragaki  阅读(281)  评论(0编辑  收藏  举报