Submission #2012042
Source Code Expand
#include "bits/stdc++.h"
#include <sys/timeb.h>
#include <fstream>
#include <random>
#include <chrono>
using namespace std;
#define repr(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define rep(i,n) repr(i,0,n)
#define reprrev(i,a,b) for(int i=(int)(b)-1;i>=(int)(a);i--)
#define reprev(i,n) reprrev(i,0,n)
#define repi(itr,ds) for(auto itr=ds.begin();itr!=ds.end();itr++)
#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
#define mp make_pair
#define mt make_tuple
#define INF 1050000000
//#define INFL 9223372036854775807LL
#define EPS (1e-10)
#define MOD 1000000007
#define PI 3.1415926536
#define RMAX 4294967295
typedef long long ll;
typedef pair<int, int> Pi;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<bool> vb;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<double> vd;
typedef vector<Pi> vPi;
typedef vector<vector<int> > vvi;
typedef vector<vector<bool> > vvb;
typedef vector<vector<ll> > vvll;
typedef vector<vector<char> > vvc;
typedef vector<vector<string> > vvs;
typedef vector<vector<double> > vvd;
typedef vector<vector<Pi> > vvPi;
typedef priority_queue<int, vector<int>, greater<int> > pqli;
typedef priority_queue<ll, vector<ll>, greater<ll> > pqlll;
typedef priority_queue<Pi, vector<Pi>, greater<Pi> > pqlP;
struct Edge {
int from, to, cost;
bool operator<(Edge e) {
return cost < e.cost;
}
};
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
template <class T>
using vec = vector<T>;
template<class T>
using pql = priority_queue<T, vector<T>, greater<T>>;
string debug_show(Pi a) {
return "(" + to_string(a.first) + "," + to_string(a.second) + ")";
}
string YN(bool y) { return (y ? "YES" : "NO"); }
string yn(bool y) { return (y ? "Yes" : "No"); }
string ON(bool y) { return (y ? "OK" : "NG"); }
template<class T>
struct augEdge {
T from, to;
int cost;
bool operator<(augEdge e) { return cost < e.cost; }
bool operator>(augEdge e) { return cost > e.cost; }
};
template<class T>
using augGraph = vector<augEdge<T>>;
int dir4[4][2] = { { 0,-1 },{ -1,0 },{ 1,0 },{ 0,1 } };
int dir8[8][2] = { { -1,-1 },{ 0,-1 },{ 1,-1 },{ -1,0 },{ 1,0 },{ -1,1 },{ 0,1 },{ 1,1 } };
// Xoroshiro128+
uint64_t randomSeed[2] = { 10, 20 };
inline static uint64_t rotl(const uint64_t x, int k) {
return (x << k) | (x >> (64 - k));
}
inline uint64_t randNext(void) {
const uint64_t s0 = randomSeed[0];
uint64_t s1 = randomSeed[1];
const uint64_t result = s0 + s1;
s1 ^= s0;
randomSeed[0] = rotl(s0, 55) ^ s1 ^ (s1 << 14); // a, b
randomSeed[1] = rotl(s1, 36); // c
return result;
}
// [a,b)のほぼ一様乱数
inline int irand(int a, int b) {
/*
static mt19937 Rand(static_cast<unsigned int>(time(nullptr)));
uniform_int_distribution<int> dist(a, b - 1);
return dist(Rand);
*/
return (randNext() % (b - a)) + a;
}
double drand(int a, int b) {
static mt19937 Rand(static_cast<unsigned int>(time(nullptr)));
uniform_real_distribution<double> dist(a, b);
return dist(Rand);
}
//高速指数関数
#define LOG2 0.693147180559945309417 //log(2)
double exp_fast(double x)
{
static double waru[7] = { 1.0 / (2 * 3 * 4 * 5 * 6),1.0 / (2 * 3 * 4 * 5),1.0 / (2 * 3 * 4),1.0 / (2 * 3),1.0 / 2,1.0,1.0 };
static unsigned long long table[16] = {
0x059B0D3158574ull, // 2^( 1 /32)-1
0x11301D0125B51ull, // 2^( 3 /32)-1
0x1D4873168B9AAull, // 2^( 5 /32)-1
0x29E9DF51FDEE1ull, // 2^( 7 /32)-1
0x371A7373AA9CBull, // 2^( 9 /32)-1
0x44E086061892Dull, // 2^( 11 /32)-1
0x5342B569D4F82ull, // 2^( 13 /32)-1
0x6247EB03A5585ull, // 2^( 15 /32)-1
0x71F75E8EC5F74ull, // 2^( 17 /32)-1
0x82589994CCE13ull, // 2^( 19 /32)-1
0x93737B0CDC5E5ull, // 2^( 21 /32)-1
0xA5503B23E255Dull, // 2^( 23 /32)-1
0xB7F76F2FB5E47ull, // 2^( 25 /32)-1
0xCB720DCEF9069ull, // 2^( 27 /32)-1
0xDFC97337B9B5Full, // 2^( 29 /32)-1
0xF50765B6E4540ull, // 2^( 31 /32)-1
};
double y = 1.0 / (2 * 3 * 4 * 5 * 6 * 7), *p = waru, z, r;
int q;
unsigned long long w;
z = x*(16.0 / LOG2);
q = (int)z - (x<0);
r = x - ((q << 1) + 1)*(LOG2 / 32.0);
w = (unsigned long long)(1023 + (q >> 4)) << 52 ^ table[q & 0xF];
z = *(double*)&w;
do {
y = y*r + (*p);
p++;
} while (p < waru + 7);
return y*z;
}
#undef LOG2
//=======ここまでテンプレート===============================================
#define DEBUG false
/*
#include"toolkit\graph\fullgraph.h"
#include"toolkit\graph\kingsgraph_square.h"
#include"toolkit\graph\randomgraph.h"
//*/
vi weight, conw;
Graph G;
int V, E, Vemb, Eemb, SIZE;
int idx(Pi p) {
return p.first * SIZE + p.second + 1;
}
class State {
int _score;
public:
vPi match;
int swapa, swapb;
State(int v) :_score(-1), match(vPi(V)) {}
bool operator<(State s) { return _score < s.score(); }
bool operator>(State s) { return _score > s.score(); }
int score() {
if (_score >= 0)return _score;
_score = 0;
rep(i, V) {
for (auto e : G[i]) {
if (abs(match[e.from].first - match[e.to].first) <= 1 && abs(match[e.from].second - match[e.to].second) <= 1) {
_score += e.cost;
}
}
}
return _score /= 2;
}
void reset_score() { _score = -1; }
void Swap(int a, int b) {
// スコア取り消し
for (auto e : G[a]) {
if (abs(match[e.from].first - match[e.to].first) <= 1 && abs(match[e.from].second - match[e.to].second) <= 1) {
_score -= e.cost;
}
}
for (auto e : G[b]) {
if (abs(match[e.from].first - match[e.to].first) <= 1 && abs(match[e.from].second - match[e.to].second) <= 1) {
_score -= e.cost;
}
}
// スワップ
swap(match[a], match[b]);
// スコア加算
for (auto e : G[a]) {
if (abs(match[e.from].first - match[e.to].first) <= 1 && abs(match[e.from].second - match[e.to].second) <= 1) {
_score += e.cost;
}
}
for (auto e : G[b]) {
if (abs(match[e.from].first - match[e.to].first) <= 1 && abs(match[e.from].second - match[e.to].second) <= 1) {
_score += e.cost;
}
}
}
void randomSwap() {
swapa = irand(0, V);
swapb = irand(0, V);
Swap(swapa, swapb);
}
/*
void randomNearSwap() {
swapa = irand(0, V);
int d = irand(0, 4);
Pi pb;
do {
pb = mp(match[swapa].first + dir4[d][0], match[swapa].second + dir4[d][1]);
d = irand(0, 4);
} while (dict.find(idx(pb)) == dict.end());
swapb = dict[idx(pb)];
Swap(swapa, swapb);
}
*/
void redo() {
Swap(swapa, swapb);
}
void debug_show() {
cout << "debug_show(): " << endl;
cout << "score: " << score() << endl;
rep(i, V) {
cout << i + 1 << " " << idx(match[i]) << endl;
}
}
void ans_show() {
rep(i, V) {
cout << i + 1 << " " << idx(match[i]) << endl;
}
}
};
State next(State st) {
State newState = st;
newState.reset_score();
newState.randomSwap();
return newState;
}
/*
State nearNext(State st) {
State newState = st;
newState.reset_score();
newState.randomNearSwap();
return newState;
}
*/
int main(void) {
// 乱数シード作成
static mt19937 Rand(static_cast<unsigned int>(time(nullptr)));
uniform_int_distribution<uint64_t> dist(1, ULLONG_MAX);
randomSeed[0] = dist(Rand);
randomSeed[1] = dist(Rand);
chrono::system_clock::time_point start = chrono::system_clock::now();
scanf("%d %d", &V, &E);
G = Graph(V);
weight = vi(V);
conw = vi(V);
rep(i, E) {
int u, v, w;
scanf("%d %d %d", &u, &v, &w);
u--; v--;
G[u].push_back(Edge{ u,v,w });
G[v].push_back(Edge{ v,u,w });
weight[u] += w * 2;
weight[v] += w * 2;
}
rep(i, V) {
for (auto e : G[i]) {
conw[i] += weight[e.to];
}
conw[i] += weight[i] * 1;
}
rep(i, V) {
weight[i] += conw[i];
}
vPi nodes(V);
rep(i, V) {
nodes[i] = mp(weight[i], i);
}
sort(rall(nodes));
scanf("%d %d", &Vemb, &Eemb);
rep(i, Eemb) {
int u, v;
scanf("%d %d", &u, &v);
}
SIZE = (int)(sqrt(Vemb) + 0.5);
int a = (int)sqrt(V);
int b = a;
if (a*(b + 1) <= V)b++;
if (DEBUG)cout << "a,b = " << a << "," << b << endl;
Pi center = mp(0, 0);
vPi dir = { { 0,1 },{ 1,0 },{ 0,-1 },{ -1,0 } };
if (a == b) {
center = mp(a / 2, a / 2);
if (a % 2 == 0) {
dir = { { -1,0 },{ 0,-1 },{ 1,0 },{ 0,1 } };
}
else {
dir = { { 1,0 },{ 0,1 },{ -1,0 },{ 0,-1 } };
}
}
else {
center = mp(a / 2, b / 2);
if (b % 2 == 0) {
dir = { { 0,-1 },{ 1,0 },{ 0,1 },{ -1,0 } };
}
else {
dir = { { 0,1 },{ -1,0 },{ 0,-1 },{ 1,0 } };
}
}
Pi pos = center;
int cnt = 0, step = 1, d = 0;
State st(V);
while (true) {
try {
rep(k, 2) {
rep(i, step) {
if (DEBUG) {
cout << "======" << endl;
cout << "pos: " << debug_show(pos) << endl;
cout << "dir[" << d << "]: " << debug_show(dir[d]) << endl;
}
st.match[nodes[cnt].second] = pos;
//st.dict[idx(pos)] = nodes[cnt].second;
pos.first += dir[d].first;
pos.second += dir[d].second;
cnt++;
if (cnt == V) {
//goto finish;
}
}
d = (d + 1) % 4;
if (pos == mp(a, 0)) {
break;
}
}
if (pos == mp(a, 0)) {
break;
}
step++;
}
catch (char *e) {
cout << e << endl;
return 0;
}
}
int res = V - a*b;
if (res == b - 1) {
rep(i, res) {
st.match[nodes[cnt].second] = pos;
//st.dict[idx(pos)] = nodes[cnt].second;
pos.second++;
cnt++;
}
}
else {
pos = mp(a, 1);
rep(i, res) {
st.match[nodes[cnt].second] = pos;
//st.dict[idx(pos)] = nodes[cnt].second;
pos.second++;
cnt++;
}
}
finish:
State bestState = st;
int bestScore = st.score();
int currentScore = bestScore;
const ll T = 9900; // 終了時間
const int R = 1000000; // 適当な値
const double startTemp = 100; // 初期温度
const double endTemp = 30; // 終了温度
// 経過時間を記録
ll t = chrono::duration_cast<std::chrono::milliseconds>(chrono::system_clock::now() - start).count();
int iteration = 0;
while (t < T) {
//iteration++;
rep(i, 10000) {
st.randomSwap();
// 次の状態へ移行
int nextScore = st.score();
// 現在の温度(最初はstartTemp, 最後はendTemp)
double temp = startTemp + (endTemp - startTemp)*t / T;
// 焼きなましによる遷移確率(スコアが改善すれば必ず遷移)
double probability = exp_fast((nextScore - currentScore) / temp);
// 遷移するか否か
bool FORCE_NEXT = probability * R >(double)(randNext() % R);
if (FORCE_NEXT /*nextScore > currentScore*/) {
// 遷移を確定させる
currentScore = nextScore;
if (currentScore > bestScore) {
// 最良の状態とスコアを記録
bestScore = currentScore;
bestState = st;
}
}
else {
// 前の状態に戻る
st.redo();
}
}
// 経過時間を更新
t = chrono::duration_cast<std::chrono::milliseconds>(chrono::system_clock::now() - start).count();
}
if (DEBUG) cout << "itteration: " << iteration << endl;
if (DEBUG) bestState.debug_show();
bestState.ans_show();
//st.ans_show();
return 0;
}
Submission Info
Submission Time |
|
Task |
A - Problem 1 |
User |
furuya1223 |
Language |
C++14 (GCC 5.4.1) |
Score |
69763 |
Code Size |
11302 Byte |
Status |
AC |
Exec Time |
9933 ms |
Memory |
1024 KB |
Compile Error
./Main.cpp: In function ‘int main()’:
./Main.cpp:271:24: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
scanf("%d %d", &V, &E);
^
./Main.cpp:277:32: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
scanf("%d %d %d", &u, &v, &w);
^
./Main.cpp:300:30: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
scanf("%d %d", &Vemb, &Eemb);
^
./Main.cpp:303:25: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
scanf("%d %d", &u, &v);
^
Judge Result
Set Name |
sample_00 |
sample_01 |
random_00 |
random_01 |
random_02 |
random_03 |
random_04 |
random_05 |
random_06 |
random_07 |
random_08 |
full_00 |
full_01 |
full_02 |
full_03 |
full_04 |
full_05 |
full_06 |
full_07 |
full_08 |
sparse_00 |
sparse_01 |
sparse_02 |
sparse_03 |
sparse_04 |
sparse_05 |
sparse_06 |
sparse_07 |
random_max |
full_max |
Score / Max Score |
7 / 1000000 |
150 / 1000000 |
1163 / 1000000 |
5168 / 1000000 |
3193 / 1000000 |
4236 / 1000000 |
626 / 1000000 |
3330 / 1000000 |
4050 / 1000000 |
3851 / 1000000 |
4103 / 1000000 |
5069 / 1000000 |
3357 / 1000000 |
129 / 1000000 |
1657 / 1000000 |
3162 / 1000000 |
6008 / 1000000 |
1405 / 1000000 |
2760 / 1000000 |
3052 / 1000000 |
355 / 1000000 |
469 / 1000000 |
336 / 1000000 |
356 / 1000000 |
600 / 1000000 |
279 / 1000000 |
414 / 1000000 |
453 / 1000000 |
3631 / 1000000 |
6394 / 1000000 |
Status |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Set Name |
Test Cases |
sample_00 |
00_sample_00 |
sample_01 |
00_sample_01 |
random_00 |
10_random_00 |
random_01 |
10_random_01 |
random_02 |
10_random_02 |
random_03 |
10_random_03 |
random_04 |
10_random_04 |
random_05 |
10_random_05 |
random_06 |
10_random_06 |
random_07 |
10_random_07 |
random_08 |
10_random_08 |
full_00 |
20_full_00 |
full_01 |
20_full_01 |
full_02 |
20_full_02 |
full_03 |
20_full_03 |
full_04 |
20_full_04 |
full_05 |
20_full_05 |
full_06 |
20_full_06 |
full_07 |
20_full_07 |
full_08 |
20_full_08 |
sparse_00 |
30_sparse_00 |
sparse_01 |
30_sparse_01 |
sparse_02 |
30_sparse_02 |
sparse_03 |
30_sparse_03 |
sparse_04 |
30_sparse_04 |
sparse_05 |
30_sparse_05 |
sparse_06 |
30_sparse_06 |
sparse_07 |
30_sparse_07 |
random_max |
60_random_max_00 |
full_max |
70_full_max_00 |
Case Name |
Status |
Exec Time |
Memory |
00_sample_00 |
AC |
9901 ms |
256 KB |
00_sample_01 |
AC |
9902 ms |
256 KB |
10_random_00 |
AC |
9904 ms |
256 KB |
10_random_01 |
AC |
9911 ms |
896 KB |
10_random_02 |
AC |
9911 ms |
896 KB |
10_random_03 |
AC |
9921 ms |
640 KB |
10_random_04 |
AC |
9904 ms |
256 KB |
10_random_05 |
AC |
9904 ms |
768 KB |
10_random_06 |
AC |
9905 ms |
768 KB |
10_random_07 |
AC |
9920 ms |
512 KB |
10_random_08 |
AC |
9929 ms |
768 KB |
20_full_00 |
AC |
9933 ms |
768 KB |
20_full_01 |
AC |
9903 ms |
384 KB |
20_full_02 |
AC |
9903 ms |
256 KB |
20_full_03 |
AC |
9918 ms |
256 KB |
20_full_04 |
AC |
9906 ms |
384 KB |
20_full_05 |
AC |
9903 ms |
896 KB |
20_full_06 |
AC |
9910 ms |
256 KB |
20_full_07 |
AC |
9911 ms |
384 KB |
20_full_08 |
AC |
9918 ms |
384 KB |
30_sparse_00 |
AC |
9903 ms |
384 KB |
30_sparse_01 |
AC |
9902 ms |
256 KB |
30_sparse_02 |
AC |
9902 ms |
256 KB |
30_sparse_03 |
AC |
9902 ms |
256 KB |
30_sparse_04 |
AC |
9903 ms |
384 KB |
30_sparse_05 |
AC |
9902 ms |
256 KB |
30_sparse_06 |
AC |
9902 ms |
256 KB |
30_sparse_07 |
AC |
9902 ms |
256 KB |
60_random_max_00 |
AC |
9907 ms |
1024 KB |
70_full_max_00 |
AC |
9924 ms |
896 KB |