码迷,mamicode.com
首页 > 其他好文 > 详细

15年-ICPC长春-网络赛

时间:2015-09-18 13:36:33      阅读:305      评论:0      收藏:0      [点我收藏+]

标签:

ID name  status one word  
 POJ 5437 Alisha’s Party 赛后AC、 优先队列,模拟。对时间t排序
技术分享
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;

struct Node {
    char name[210];
    int val;
    int t;
    bool operator < (const Node &a) const {
       if (a.val != val)
        return a.val > val;
       else return a.t < t;
    }
}node[150010];

struct Open {
    int t, per;
}open[150010];

bool cmp(Open a, Open b) {
    return a.t < b.t;
}

Node rem[150010];
priority_queue<Node>que;

int main() {
    int k, m, q;
    int t;
    scanf("%d", &t);
    while (t--) {
        memset(open, 0, sizeof(open));
        memset(rem, 0, sizeof(rem));
        scanf("%d%d%d", &k, &m, &q);
        for (int i=0; i<k; ++i) {
            scanf("%s%d", node[i].name, &node[i].val);
            node[i].t = i;
        }

        for (int i=0; i<m; ++i) {
            scanf("%d%d", &open[i].t, &open[i].per);
        }
        while (!que.empty()) {
            que.pop();
        }
        sort(open, open+m, cmp);

        int cnt = 0;
        int t = 0;
        for (int i=0; i<m; ++i) {
            if (t < open[i].t) {
                for (int j=t; j < open[i].t; ++j) {
                    que.push(node[j]);
                }
                t = open[i].t;
            }
            int num = 0;
            while(num < open[i].per && !que.empty() && cnt < k) {
                rem[cnt++] = que.top();
                num++;
                que.pop();
            }
        }

         if (open[m-1].t < k) {
            for (int i=open[m-1].t; i<k; ++i) {
                que.push(node[i]);
            }
         }

         while(!que.empty() && cnt < k) {
            rem[cnt++] = que.top();
            que.pop();
         }

         int a;
         for (int i=0; i<q; ++i) {
            scanf("%d", &a);
            if (i == 0)
            printf("%s", rem[a-1].name);
            else printf(" %s", rem[a-1].name);
         }
         printf("\n");
    }
    return 0;
}
View Code

 

POJ 5438 Ponds 赛后AC 循环链表
技术分享
#include <queue>
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;

#define maxn 100000+50  // 边的个数
#define maxm 10000+50  // 节点个数
int t, p, m, a, b;

int val[maxm];
int head[maxm];
int deg[maxm];
bool vis[maxm];
long long ans, temp;
int num;

struct Edge {
  int v, next;
}edge[maxn];

int totEdge;
queue<int>que;

void addEdge(int a, int b) {
   edge[totEdge].v = b;
   edge[totEdge].next = head[a];
   head[a] = totEdge++;
}

void init() {
   memset(head, -1, sizeof(head));
   memset(edge, 0, sizeof(edge));
   memset(val, 0, sizeof(val));
   memset(vis, 0, sizeof(vis));
   memset(deg, 0, sizeof(deg));
   totEdge = 0;
   ans = 0;
   while(!que.empty())
    que.pop();
}


void topSort() {
    for (int i=1; i<=p; ++i) {
        if (deg[i] == 0)
            vis[i] = true;
        if (deg[i] == 1) {
            vis[i] = true;
            que.push(i);
        }
    }

    while(!que.empty()) {
        int top = que.front();
        //cout << top << "===\n";
        que.pop();
        for (int i=head[top]; i!=-1; i=edge[i].next) {
            int v = edge[i].v;
            //cout << v << "----\n";
            deg[v]--;
            if (!vis[v]) {
                if (deg[v] == 0)
                    vis[v] = true;
                else if (deg[v] == 1) {
                    vis[v] = true;
                    que.push(v);
                }
            }
        }
        //cout << "***\n";
    }
}

void Dfs(int u, int fa) {
//    cout << val[u] << "===" << u << endl;;
    num += 1;
    temp += val[u];
    vis[u] = true;
    for (int i=head[u]; i!=-1; i=edge[i].next) {
        int v = edge[i].v;
        if (!vis[v] && v != fa) {
            Dfs(v, u); // u开头的这条链上的最后一个子节点,如果是u ,就说明到环的开始了。
        }
    }
}

int main() {
   cin >> t;
   while (t--) {
      init();
      cin >> p >> m;

      for (int i=1; i<=p; ++i) {
        cin >> val[i];
      }

      for (int i=0; i<m; ++i) {
        cin >> a >> b;
        addEdge(a, b);
        addEdge(b, a);
        deg[a]++;
        deg[b]++;
      }
      topSort();
      for (int i=1; i<=p; ++i) {
        num = 0;
        temp = 0;
        if (!vis[i])
        Dfs(i, 0);
        if (num & 1) {
            ans += temp;
        }
      }
      cout << ans << endl;
   }
   return 0;
}
View Code

 

POJ 5439 Aggregated Counting      
POJ 5440 Clock Adjusting      
POJ 5441 Travel 赛后AC 并查集+离线化。注音可以休息、
技术分享
// 先对边按权值排序,然后对询问按照权值排序。
// 每次在满足当前条件下,遍历。把两个端点所在的集合
// 并起来。此时增加的pair数就是2*num1*num2.
// 因为已经对询问按照权值排序。所以后面的集合一定会覆盖前面的、
// 所以只要一直询问下去。记录就可以了。
// 有一点并查集离线查询的地方。

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;

#define maxn 201000  // 节点数
#define maxm 51000  // 询问数
#define tot 1001000  // 边数

int t, n, m, q;
int num[maxn]; // 维护每个节点当前所在集合的节点个数、
int ans[maxm];  // 保存每次询问的结果、
int fa[maxn]; // 并查集

struct Node {
    int st, ed, dis;
}node[tot];

int cmp(Node a, Node b) {
    return a.dis < b.dis;
}

struct Querry{
  int id, ask;
}que[maxm];

void init() {
   for (int i=1; i<=n; ++i) {
       fa[i] = i;
       num[i] = 1;
   }
   memset(ans, 0, sizeof(ans));
}

int cmp2(Querry a, Querry b) {
    return a.ask < b.ask;
}

int find_(int i) {
    if (fa[i] == i) return i;
    else return fa[i] = find_(fa[i]);
}

int main() {
  int a, b, d;
  scanf("%d", &t);
  while (t--) {
    scanf("%d%d%d", &n, &m, &q);
    init();
    for (int i=1; i<=m; ++i) {
        scanf("%d%d%d", &a, &b, &d);
        node[i].st = a;
        node[i].ed = b;
        node[i].dis = d;
    }
    sort(node+1, node+1+m, cmp);
    for (int i=0; i<q; ++i) {
        scanf("%d", &que[i].ask);
        que[i].id = i+1;
    }
    sort(que, que+q, cmp2);

    int now = 1;
    int tempans = 0;
    int flag = 0;

    for (int i=0; i<q; ++i) {
       flag = que[i].id;
       for(; node[now].dis<=que[i].ask && now<=m; now++) {
            int t1 = node[now].st;
            int t2 = node[now].ed;
            if (t1 == t2) {
                continue;
            }
            if (find_(t1) == find_(t2)) {
                continue;
            }
            else if (find_(t1) != find_(t2)) {
                tempans += 2*num[find_(t1)]*num[find_(t2)];
                num[find_(t1)] += num[find_(t2)];
                fa[find_(t2)] = find_(t1);
            }
        }
       ans[flag] += tempans;
    }
    for (int i=1; i<=q; ++i) {
        printf("%d\n", ans[i]);
    }
  }
  return 0;
}
View Code

 

POJ 5442 Favorite Donut      
POJ 5443 The Water Problem 题如其名,水题。 ..........就是水。  
POJ 5444 Elven Postman 赛后AC 二叉树建和遍历。
技术分享
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;

struct Tree {
   int l, r;
}node[1010];

bool flag;

void init() {
   memset(node, 0, sizeof(node));
}

void addNode(int u, int c) {
    if (node[u].l==0 && u<c) {node[u].l = c;return;}
    else if (node[u].r==0 && u>c) {node[u].r = c;return;}
    else if (u<c) addNode(node[u].l, c);
    else addNode(node[u].r, c);
}

void find(int u, int c) {
   if (u == c)
    return;
   else if (u<c) {
    cout << W;
    find(node[u].l, c);
   }
   else if (u > c) {
    cout << E;
    find(node[u].r, c);
   }
}

int main() {
   int t, n, q, r, c;
   cin >> t;
   while(t--) {
    init();
    cin >> n;
    cin >> r;
    node[r].l = node[r].r = 0;

    for (int i=1; i<n; ++i) {
        cin >> c;
        addNode(r, c);
    }
    cin >> q;
    for (int i=0; i<q; ++i) {
        flag = true;
        cin >> c;
        find(r, c);
        cout << endl;
    }
   }
   return 0;
}
View Code

 

POJ 5445 Food Problem      
POJ 5446 Unknown Treasure      
POJ 5447 Good Numbers      
POJ 5448 Marisa’s Cake      
POJ 5449 Robot Dog      

很多题就是想不到思路。其实是可以做的。第一场只过了1道。。。。。。。。。人艰不拆。。。。。。

15年-ICPC长春-网络赛

标签:

原文地址:http://www.cnblogs.com/icode-girl/p/4818730.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!