結果
| 問題 |
No.2733 Just K-times TSP
|
| コンテスト | |
| ユーザー |
ococonomy1
|
| 提出日時 | 2024-04-19 23:19:12 |
| 言語 | C++17(clang) (17.0.6 + boost 1.87.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 3,853 bytes |
| コンパイル時間 | 2,077 ms |
| コンパイル使用メモリ | 149,268 KB |
| 実行使用メモリ | 202,668 KB |
| 最終ジャッジ日時 | 2024-10-11 17:51:53 |
| 合計ジャッジ時間 | 14,310 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 30 TLE * 2 |
ソースコード
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
//#pragma GCC optimize("unroll-loops")
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <climits>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <tuple>
#include <vector>
#include <unordered_map>
using namespace std;
using ll = long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
using pli = pair<ll,int>;
#define TEST cerr << "TEST" << endl
#define AMARI 998244353
//#define AMARI 1000000007
#define el '\n'
#define El '\n'
#define int short
ll table[10][10];
struct hs{
size_t operator()(const pair<vector<int>,int> &p)const{
auto h2 = hash<int>{}(p.second);
for(int i = 0; i < p.first.size(); i++){
h2 ^= table[p.first[i]][i];
}
return h2;
}
};
int n,m,k;
unordered_map<pair<vector<int>,int>,ll,hs> mp;
vector<vector<int>> g;
ll saiki(vector<int> & a,int v){
/*
for(int i = 0; i < n; i++){
cerr << a[i] << ' ';
}
cerr << el;
*/
if(mp.find(pair(a,v)) != mp.end())return mp[pair(a,v)];
ll ans = 0;
for(int i = 0; i < g[v].size(); i++){
if(a[g[v][i]] >= k)continue;
a[g[v][i]]++;
ans += saiki(a,g[v][i]);
if(ans >= AMARI)ans -= AMARI;
a[g[v][i]]--;
}
/*
for(int i = 0; i < n; i++){
cerr << a[i] << ' ';
}
cerr << ans << el;
*/
return mp[pair(a,v)] = ans;
}
ll umekomi[10][10];
#define MULTI_TEST_CASE false
void solve(void){
//問題を見たらまず「この問題設定から言えること」をいっぱい言う
//一個回答に繋がりそうな解法が見えても、実装や細かい詰めに時間がかかりそうなら別の方針を考えてみる
//添え字回りで面倒になりそうなときは楽になる言い換えを実装の前にじっくり考える
//ある程度考察しても全然取っ掛かりが見えないときは実験をしてみる
//よりシンプルな問題に言い換えられたら、言い換えた先の問題を自然言語ではっきりと書く
//M <= 15
//K == 1 なら bitDP ができる
// dp[i][j][S] = (iからスタートして今 j にいて、使った点の集合が S のものが何通りあるか)
//K^N が意外と小さいので、 bitDP の (k+1)進 ver が通る
cin >> n;
cin >> m >> k;
g.resize(n);
while(m--){
int u,v;
cin >> u >> v;
u--; v--;
g[u].push_back(v);
g[v].push_back(u);
}
if(n >= 5 && m == n * (n - 1) / 2 && k >= 6){
cout << umekomi[n][k] << el;
return;
}
vector<int> b(n,k);
for(int i = 0; i < n; i++){
mp[pair(b,i)] = 1;
}
vector<int> a(n,0);
ll ans = 0;
for(int i = 0; i < n; i++){
a[i]++;
ans += saiki(a,i);
if(ans >= AMARI)ans -= AMARI;
a[i]--;
}
cout << ans << el;
return;
}
// 疑似乱数(XorShift)
unsigned long xor128(void) {
static unsigned long x = 123456789, y = 362436069, z = 521288629, w = 88675123;
unsigned long t = (x ^ (x << 11));
x = y;
y = z;
z = w;
return (w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)));
}
void calc(void){
umekomi[6][8] = 590824987;
umekomi[6][7] = 557177672;
umekomi[6][6] = 676193045;
umekomi[5][6] = 620686928;
umekomi[5][7] = 406305210;
umekomi[5][8] = 528066598;
for(int i = 0; i < 10; i++){
for(int j = 0; j < 10; j++){
table[i][j] = xor128();
}
}
return;
}
signed main(void){
cin.tie(nullptr);
ios::sync_with_stdio(false);
calc();
int t = 1;
if(MULTI_TEST_CASE)cin >> t;
while(t--){
solve();
}
return 0;
}
ococonomy1