Test summary (CE ???)

Write directly open Solution:

(T1 due to violence simulation, without finishing)

T2:

Buso gave you a tree, this tree covered with tender new leaves, we agreed roots of this tree is 1, each node represents a leaf on the tree. If you do not know what the tree, you can not think trees are a number of edges connected graph is one less than the number of nodes. If we agreed u is the root node of the tree T, you can define a path to the root node v u for free to the figure, a simple set of nodes on the path between two nodes v (both inclusive path) . It can be shown that this is only a simple path. We define the node x is an ancestor of node y (x does not equal y), if and only if the x-y in the path to the root. Fusu now want to select a collection, a collection called it tender, to compare the set of nodes which most tender this tree. Once the collection notice there are two nodes u, v, v such that u is the ancestor, then it must v u more than the young, because v is on u grow out of the branches, then this collection is not meaningful . In other words, the selected set Fusu meet certain requirements "for any elements of the collection of the (u, v), u is not v ancestors." Fusu In fact, what most young are not interested in these nodes, he can also choose how many collections are not interested, because they are designed to ask you the following questions and topics to create a background. Fusu each node defines a weight value, specifically, we will give a parameter T, the right to a predetermined number of node i value T i. We define a set of weights young young index in the set of nodes and values. Fusu would like to ask you now, for all his collections may elect, young exponent of these collections and how much. In order to avoid excessive answer, please results 1000000007 modulo output of your answer.

ZAY Gangster layered speak several ways you can get points, respectively, at different levels,

1. Direct output answer, only the first question sub

2. violent seizure, higher complexity, but can get 30 points

3.DP

We can put this label:

Becomes this:

Consider the status of each node is represented by the child nodes

1. binary state, only two branches each node

First consider the boundary condition that the node is a leaf node, it is not even sub-sub-tree node, so his contribution to its own weight,

Consider node has two child nodes, the nodes on which the options There are four, are the left node, right node, themselves, about two nodes

Then easily inferred by the multiplication principle, the total number of sub-program of the current node is the root node of the total volume of the program plus 1, two sub-tree is the case with each other, and then count the total number of sub-tree itself is not a solution, which is +1 usefulness

The scores for each node is the root node of a sub-trees fraction multiplied by the total number of other sub-tree program is how many times they have been selected, which can be launched answers

2. Non-binary tree,

Each time the operation is the same as described above for the two leftmost subtree layer, then it as a whole, be treated under a subtree until all processing is complete subtree

According to the above thought that the whole process can be divided DP spicy!

Code:

#include <cstdio>

typedef long long int ll;

const  int maxn = 1000005 ;
const  int MOD = 1000000007 ;

template <typename T>
inline void qr(T &x) {
  char ch;
  do { ch = getchar(); } while ((ch > '9') || (ch < '0'));
  do { x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar(); } while ((ch >= '0') && (ch <= '9'));
}

int n, T;
int MU [MaxN], frog [MaxN], Jul [MaxN];
bool vis [MaxN];

struct Edge {
  int v;
  Edge *nxt;

  Edge(const int _v, Edge *h) : v(_v), nxt(h) {}
};
Edge *hd[maxn];

void dfs(const int u);

int main () {
  freopen("dzy.in", "r", stdin);
  freopen("dzy.out", "w", stdout);
  qr(n); qr(T);
  if (T) {
    for (int i = 1; i <= n; ++i) {
      MU[i] = i;
    }
  } else {
    for (int i = 1; i <= n; ++i) {
      MU[i] = 1;
    }
  }
  for (int i = 1, u, v; i < n; ++i) {
    u = v = 0; qr(u); qr(v);
    hd[u] = new Edge(v, hd[u]);
    hd[v] = new Edge(u, hd[v]);
  }
  dfs(1);
  printf("%d\n", frog[1] % MOD);
  return 0;
}

void dfs(const int u) {
  vis[u] = true;
  for (auto e = hd[u]; e; e = e->nxt) if (!vis[e->v]) {
    int v = e->v;
    dfs(v);
    frog [u] = (frog [u] * (Jul [v] + 1LL)% MOD) + (frog [v] * (Jul [u] + 1LL)% MOD);
    Jul [u] = (Jul [u] + Jul [v] + (1LL * Jul [u] * Jul [v]))% MOD;
  }
  frog[u] = (frog[u] + MU[u]) % MOD;
  ++gorf[u];
}

So strange code of wind definitely ah zay

 T3:

In a hurried retreat era, there was a painter called shallow streams, koi very fond of painting. War to Tai'an, his neighbors are scared for their lives, only he is not willing to leave no Koi pool. That evening fire garden, koi pool of demon, cover your life with peace painter.

Fusu is the story of artist and koi are deeply touched. In order to allow koi artist and continue to live together, he decided to return to extinguish fires burning in the courtyard. Painter's patio abstracted into a directed graph, each point represents a location of the fire. To quantify the size of the fire, the stronger each point Fusu to a fire, the larger the value of the fire, the fire represent this point. Wind to help the fire, the fire by the wind, for each ignition point, so that winds are likely because fire spread to other points. Each edge of the directed graph <u, v> is representative of the fire from the point v to the point u diffusion. Note that a point may spread to many points, it could be a lot of fire points diffuse together into. In order not to put out the fire because the source so that the painter found someone to help him fire, at any time, Fusu can not extinguish any fire not to be a proliferation point of any points. All sides after the fire was put out one point, the fire on behalf of diffusion that point will disappear. It should be noted that, although the edge is gone, but the point spread to all points of the attributes except the penetration will not change, will not disappear. Because of the limited time through, Fusu can exterminate most k fire points. Busy writing surface Fusu title he did not have time to calculate the maximum number of values ​​can put out the fire, so he put this question to you.

Questions face version easy to understand: give you a directed graph, each point has a right to the point. You can choose any point into a degree, obtain its weight and to point it out to its edge and omitted from the FIG. Can not be selected without any time point of penetration. Up to select k points, seeking the right to get the maximum number of points.   md I spent 10 minutes reading the title you tell me Starter Edition? ? ? ! ! ! 

The old rules:

1. Output Sample 5 minutes (I did not even finish output to output the answer, but down from the stick achievements template T2, and a wave of choking the operation CE)

2. Search storm

3. topological sorting + greedy (there is not enough time this idea but this topic actually damn sweet background )

4. Also topology to ring contraction points (Tarjan) with a deep search principles and properties strongly connected component, a greedy search tree for complete ...

TM I just set the whole of what?

We hear almost the entire afternoon solution to a problem is such a state:

Ah ... is this ... this ... um, um speak good!

1 minite later

(Whisper) you understand?

Code offer:

#include <cstdio>
#include <algorithm>
#include <functional>
#ifdef ONLINE_JUDGE
#define freopen(a, b, c)
#endif

typedef long long int ll;

namespace IPT {
  const int L = 1000000;
  char buf[L], *front=buf, *end=buf;
  char GetChar() {
    if (front == end) {
      end = buf + fread(front = buf, 1, L, stdin);
      if (front == end) return -1;
    }
    return *(front++);
  }
}

template <typename T>
inline void qr(T &x) {
  char ch = IPT::GetChar(), lst = ' ';
  while ((ch > '9') || (ch < '0')) lst = ch, ch=IPT::GetChar();
  while ((ch >= '0') && (ch <= '9')) x = (x << 1) + (x << 3) + (ch ^ 48), ch = IPT::GetChar();
  if (lst == '-') x = -x;
}

const  int maxn = 1000006 ;

struct Edge {
  int v;
  Edge *nxt;

  Edge(const int _v, Edge *h) : v(_v), nxt(h) {}
};
Edge *hd[maxn];

int n, m, k, vistime, top, scnt;
int MU[maxn], dfn[maxn], low[maxn], stack[maxn], belong[maxn], minv[maxn];
bool instack[maxn], haveind[maxn];

void tarjan(const int u);

int main () {
  freopen("zay.in", "r", stdin);
  freopen("zay.out", "w", stdout);
  qr(n); qr(m); qr(k); MU[0] = 2333;
  for (int i = 1; i <= n; ++i) qr(MU[i]);
  for (int i = 1, u, v; i <= m; ++i) {
    u = v = 0; qr(u); qr(v);
    hd[u] = new Edge(v, hd[u]);
  }
  for (int i = 1; i <= n; ++i) if (!dfn[i]) {
    Tarjan (i);
  }
  for (int u = 1; u <= n; ++u) {
    for (auto e = hd[u]; e; e = e->nxt) if (belong[u] != belong[e->v]) {
      haveind[belong[e->v]] = true;
    }
  }
  for (int i = 1; i <= scnt; ++i) if (!haveind[i]) {
    MU [minv [i]] = 0 ;
  }
  std::nth_element(MU + 1, MU + 1 + k, MU + 1 + n, std::greater<int>());
  int ans = 0;
  for (int i = 1; i <= k; ++i) {
    ans += MU[i];
  }
  printf("%d\n", ans);
  return 0;
}

void tarjan(const int u) {
  DFN [u] = low [i] ++ = vistime;
  instack[stack[++top] = u] = true;
  for (auto e = hd[u]; e; e = e->nxt) {
    int v = e->v;
    if (!dfn[v]) {
      Tarjan (v);
      low[u] = std::min(low[u], low[v]);
    } else if (instack[v]) {
      low[u] = std::min(low[u], dfn[v]);
    }
  }
  if (dfn[u] == low[u]) {
    int v, &_mv = minv[++scnt];
    do {
      instack[v = stack[top--]] = false;
      belong[v] = scnt;
      if (MU[v] < MU[_mv]) _mv = v;
    } while (v != u);
  }
}

Do not fight the gods using namespace std's ...

Explain the content on here, look over training can not understand ...

Considering the DAG into the ordinary what will happen to the map.

With subtasks Tip 3, we can consider the whole point reduction map, turning it into a DAG do.

For a DAG, it will be apparent by subtask 3 that the selected adjustment procedure for a case where each strongly connected components other than the selected number of points of each other. Therefore, the discussion below only the case of a strongly connected component inside.

Obviously a strongly connected components can be regarded as a tree with a lot of side outward obtained.

The definition of an outgoing tree: a tree of any node outgoing or a leaf node, or all edges between it and the children are directed by its children.

An outward tree is clearly a DAG. Accordance with the previous description of the DAG case, it is clear that we can select any node except for the root node.

Since a strongly connected component is the internal communication with each other, so we might Imperial a root point.

For a strongly connected component no penetration, we might Chin smallest fixed point right to the root. This is clearly the best choice is.

For a strongly connected component of the degree, we might have a point that Imperial penetration of the root. In this way only the time to select the root node as the root node there degrees, the root node can be selected. So this all strongly connected components may be selected. This is clearly the best.

Such comprehensive discussion above, there is the strongly connected components can pick degrees, strongly connected components not removed the smallest dot of the right point. The remaining greedy take the first k it.

Once tarjan complexity is O (n + m), the former is selected from k points can be sorted out. Thus the overall complexity of O (m + nlogn), scored 35 points is desirable. Noting the complexity of the bottleneck on the sequencing, we only need to consider the k big size without requiring particular relationships between the first k, then uses std :: nth_element () function can be reduced complexity of O (n + m) . Expect to score 40 points. Note that the input scale to the 107 level, you need to realize fread read optimization.

nth_element () function is a theory of complexity is O (n) sorting function (so 6?)

Guess you like

Origin www.cnblogs.com/648-233/p/11067779.html