(1)题意
给出M组关系,问是否有一个排列,能表示A[i]和B[i]相邻
(2)思路
考虑如果有环,显然不能满足排列,因为排列中度数最多为2,若有超过2的显然也不行。因此用并查集维护一下即可。
(3)代码
- #include
- #define rep(i,z,n) for(int i = z;i <= n; i++)
- #define per(i,n,z) for(int i = n;i >= z; i--)
- #define PII pair
- #define fi first
- #define se second
- #define vi vector
- #define vl vector
- #define pb push_back
- #define sz(x) (int)x.size()
- #define all(x) (x).begin(),(x).end()
- using namespace std;
- using ll = long long;
- const int N = 2e5 + 10;
- struct DSU {
- vector<int> f,siz;
- int n;
- DSU(int _n) {
- n = _n;
- f.resize(n + 1);
- siz.resize(n + 1,1);
- iota(f.begin(),f.end(),0);
- }
-
- inline int find(int x) {
- if(x == f[x]) return x;
- return f[x] = find(f[x]);
- }
-
- inline bool same(int x,int y) {
- x = find(x),y = find(y);
- return x == y;
- }
-
- inline void merge(int x,int y) {
- if(same(x,y)) return ;
- x = find(x),y = find(y);
- siz[y] += siz[x];
- f[x] = y;
- }
-
- //目前连通块个数
- inline int connect() {
- int res = 0;
- for(int i = 1;i <= n;i ++) {
- res += (i == find(i));
- }
- return res;
- }
-
- //求某一个联通块得大小
- inline int count(int x) {
- x = find(x);
- return siz[x];
- }
- };
- int deg[N];
- void solve()
- {
- int n,m;
- cin >> n >> m;
- DSU dsu(n);
- bool cycle = false;
- rep(i,1,m) {
- int u,v;
- cin >> u >> v;
- if(dsu.same(u,v)) {
- cycle = true;
- }
- else {
- dsu.merge(u,v);
- deg[u] ++,deg[v] ++;
- }
- }
- if(cycle) {
- cout << "No" << '\n';
- return;
- }
- rep(i,1,n) {
- if(deg[i] > 2) {
- cout << "No" << '\n';
- return;
- }
- }
- cout << "Yes" << '\n';
- }
- int main()
- {
- ios::sync_with_stdio(false);
- cin.tie(0),cout.tie(0);
- int T = 1;
- // cin >> T;
- while(T --) solve();
- return 0;
- }
E - Minimal payments (atcoder.jp)
(1)题意
阿特科德王国使用的硬币有N种: A1日元、A2日元、……、AN日元硬币。 如果只用这些硬币支付一件价值X日元的商品,那么支付时使用的硬币和作为零钱退回的硬币的最少总数是多少? 当Y是一个至少为X的整数时,求正好表示Y日元所需的硬币数与正好表示Y−X日元所需的硬币数的最小和。 (2)思路 对于每一种支付,我们有两种决策,要么就是支付到最多的,然后剩下的用小币去凑,要么就是你多支付一张,小的就凑你多出来的那部分,因此直接记忆化dp即可。 (3)代码 (1)题意 有一个长度为N的A数组,A[i]代表A对i这件物品的好感度,有一个长度为N的B数组,B[i]代表B对i这件物品的好感度,现在让你求有多少对[i,j]满足A[i] >= A[j]并且B[i] <= B[j]。 (2)思路 很明显这是一个二维偏序问题,我们直接sort+树状数组秒了(特殊处理一下重复的就行)。 (3)代码 H - Minimum Coloring (atcoder.jp) (1)题意 我们有一个行数为H,列数为W的网格。让 (i,j)表示从上往下第i行和从左往下第j列的正方形。在这个网格上有N个白色棋子,编号为1到N。棋子i在(Ai,Bi)上。你可以支付Ci的费用将棋子i变成黑棋,求每行每列至少有一颗黑子所需的最小总费用。 (2)思路 很显然的一个列拆点,把行向列连边的费用流,不过这题特殊的是必须行列都有,我们考虑如下建图。 把每一行当作一个节点,从S->i流M的流量,从i->P流m-1的流量,从p向每一列流n-1的流量,从列向t流n的流量,最后给点的边的[u,v]的价值w 相当于从u->(v + n)流1的流量费用为w,最后跑费用流即可。因为题目保证会出现每行每列至少出现一个,因此一定会把n*m的流量流满。 (3)代码
这里,1=A1<…