لینک سوال: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3158
نوع سوال: Brute-Force (امتحان تمام حالات)
توضیح راه حل : با توجه به اینکه ابعاد جدول زیاد نیست (هر بعد حداکثر 7)، می توان تمام حالت های تقسیم جدول به دو قسمت را امتحان کرد. هر حالت تقسيم هم عبارت است از دنباله ی
، که در آن
است، به این معنی که از سطر اول
تای سمت چپ را برای شخص اول انتخاب می کنیم و بقیه را برای شخص دوم و الا آخر.
در زیر کد من برای این سوال را مشاهده می کنید:
#include <iostream> #include <algorithm> #include <cstdlib> using namespace std; int board[7][7], m, n, t; int result; void bt( int idx, int diff ) { if( idx == n ) result = min( result, abs( diff ) ); else { for( int i = 0; i < m - 1; i ++ ) { int a = board[idx][ i ]; int b = board[idx][ m - 1 ] - a; bt( idx + 1, diff + b - a ); } } } int main() { while( cin >> n >> m ) { for( int i = 0; i < n; i ++ ) for( int j = 0; j < m; j ++ ) { cin >> board[i][j]; if( j > 0 ) board[i][j] += board[i][j - 1]; } cin >> t; result = 0x7fffffff; bt( 0, 0 ); if( result <= t ) cout << result << endl; else cout << "You'd better buy another one!" << endl; } return 0; }
لینک سوال: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3159
نوع سوال: جستجوی دودوئی
توضیح راه حل : با توجه به اینکه اگر در زمان T بتوان ترتیب و سرعت magpie ها را طوری تعیین کرد که در یک نقطه جمع شوند، در زمان های بالاتر نیز امکان پذیر است، می توان از جستجوی دودوئی برای حل این مساله استفاده کرد.
بخشی از کد که به جستجوی دودوئی می پردازد و نتیجه را چاپ می کند:
double L = 0, R = 1e9; while( L < R - 1e-6 ) if( check( (L + R) * 0.5 ) ) R = (L + R) * 0.5; else L = (L + R) * 0.5; cout.precision(10); cout.setf(ios::fixed | ios::showpoint); cout << L << endl;
حال به بررسی اینکه چگونه می توان چک کرد که آیا این کار در زمان T امکان پذیر است می پردازیم. با توجه به اینکه اگر زمان هل دادن یک magpie برابر با s باشد، در زمان
مکان هندسی ای که این magpie می توان در آن قرار داشته باشد داخل مستطیلی با گوشه های
و
است، در صورتیکه ترتیب هل دادن magpie ها مشخص باشد، می توان محدوده ی مکان هندسی تمام آن ها را مشخص کرد. اگر اشتراک تمام مستطیل ها خالی نباشد، این کار در زمان T با ترتیب معلوم شده امکان پذیر است، و در غیر این صورت امکان پذیر نیست. بنابراین با توجه به اینکه تعداد magpie های زیاد نیست، می توان تمام ترتیب ها را امتحان کرد تا مشخص شود که این کار در زمان T امکان پذیر است یا نه.
برای مشخص کردن ترتیب ها، می توان از تابع next_permutation زبان ++C استفاده کرد، يا از تابعی بازگشتی که توسط خودتان پیاده سازی می شود استفاده کرد. با توجه با استفاده از تابع بازگشتی می توان حالت هایی که در نیمه ی راه نامعتبر می شوند (بدون مشخص کردن بقیه ی دنباله) را تشخیص داد و سرعت کار بیشتر می شود، من از تابع بازگشتی استفاده کردم.
برای تعیین اشتراک دو مستطیل، بازه x و بازه y آن ها را جداگانه اشتراک می گیریم. اشتراک دو بازه
و
نیز برابر است با
، که اگر انتهای این بازه ی جدید از ابتدای آن کوچکتر باشد به معنای تهی بودن بازه است، و اگر بازه x یا بازه y مستطیلی تهی باشد، آن مستطیل تهی است.
در زیر تابع check برنامه من را مشاهده می کنید:
bool mark[10]; bool bt( int idx, double xa, double xb, double ya, double yb, double r ) { if( xb < xa || yb < ya ) return false; if( idx == n ) return true; for( int i = 0; i < n; i ++ ) if( !mark[i] ) { mark[i] = true; if( bt( idx + 1, max(xa, x[i] - max(0., r - idx * t) * vx) , min(xb, x[i] + max(0., r - idx * t) * vx) , max(ya, y[i] - max(0., r - idx * t) * vy) , min(yb, y[i] + max(0., r - idx * t) * vy) , r) ) return true; mark[i] = false; } return false; } bool check( double r ) { memset( mark, 0, sizeof mark ); return bt( 0, -1e10, 1e10, -1e10, 1e10, r ); }
لینک سوال: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3160
نوع سوال: برنامه سازی پویا
توضیح راه حل : فرض کنید [mat[a][b مشخص کند که اگر ورودی مساله افراد با اندیس a تا b بود، کمترین تعداد افرادی که با انجام عملیات ذکر شده در مساله می توانند باقی بمانند چقدر است. با توجه به اینکه این بازه، در صورتیکه جفتی از آن خارج شوند، دارای یک آخرین جفتی است که خارج می شوند. دو حالت برای این جفت در نظر می گیریم:
عضو اول این جفت است. با توجه به اینکه این شخص جفت آخرین جفت خارج شونده است، هیچ شخصی از سمت چپ این شخص نمی تواند با شخصی از سمت راست این جفت خارج شود. بنابراین با فرض اینکه k جزو آخرین جفت است، جواب مساله برابر خواهد بود با
.
باید برابر با 0 باشد. و همچنین جواب مساله با فرض اینکه آخرین جفت خارج شونده a و k است، برابر با
است (در صورتیکه تمامی افراد بین این دو بتوانند خارج شوند، در غیر این صورت این حالت امکان پذیر نیست).
و جواب
می نیمم تمام مقادیر این دو حالت است. جواب نهایی مساله نیز برابر با
است (چون بیشترین تعداد افراد خارج شونده را می خواهیم پیدا کنیم، که مکمل کمترین تعداد افراد باقی مانده است).
برای آشنایی به جزئیات به کد من برای این مساله توجه کنید:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 300; int n, m, rel[N][N], mat[N][N], a, b, arr[N]; int main() { while( scanf("%d %d", &n, &m) == 2 ) { memset( rel, 0, sizeof rel ); for( int i = 0; i < m; i ++ ) { scanf("%d %d", &a, &b); rel[a][b] = rel[b][a] = true; } for( int i = 0; i < n; i ++ ) scanf("%d", &arr[i]); for( int i = n-1; i >= 0; i -- ) for( int j = i; j < n; j ++ ) if( i == j ) mat[i][j] = 1; else { mat[i][j] = 1 + mat[i+1][j]; for( int k = i + 1; k <= j; k ++ ) { if( k < j ) mat[i][j] = min( mat[i][j], mat[i][k] + mat[k + 1][j] ); if( rel[arr[i]][arr[k]] ) if( k == i + 1 || mat[i+1][k-1] == 0 ){ int t = 0; if( k < j ) t += mat[k+1][j]; mat[i][j] = min( mat[i][j], t ); } } } printf("%d\n", n - mat[0][n-1]); } return 0; }
لینک سوال: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3161
نوع سوال: حریصانه - برنامه سازی پویا
توضیح راه حل : به آسانی می توان مشاهده کرد که بهتر است زوج هایی که کنار هم نیستند را در آغاز کار اعلام کنیم. پس از این اعلام ها، و با توجه به اینکه هنوز هیچ شخصی از دنباله خارج نشده است، و تمام زوج های اعلام نشده در کنار هم قرار دارند، دنباله ی افراد را می توان به تعدادی بخش (ممکن است طول برخی بخش ها برابر با 1 باشند) تقسیم کرد که در هر بخش افراد کنار هم با یکدیگر زوج تشکیل می دهند. فرض کنید
برای دنباله ای به طول i که در آن افراد کنار هم با هم زوج هستند و افراد جدا از هم با هم زوج نیستند، بیشترین تعداد افرادی باشد که می توانیم نگه داریم. بنابراین اگر دنباله طول بخش هایی که ذکر کردیم برابر با
باشد، جواب مساله برابر است با
.
حال به چگونگی محاسبه ی آرایه dp می پردازیم. حالت های پایه آن برابرند با:
.
.
حال برای پیدا کردن
با فرض اینکه این جدول برای مقادیر کوچکتر از i پر شده است، به این گونه عمل می کنیم: اگر فرض کنیم نخستین زوجی که اعلام می کنیم
است، در این صورت جواب مساله برابر خواهد بود با
، زیرا که خود افراد طوری عمل می کنند که کمترین تعداد باقی بمانند. و مقدار
برابر خواهد بود با بیشینه این مقادیر برای انتخاب های مختلف j. بنابراین این جدول را می توان با پیچیدگی زمانی
ایجاد کرد.
در زیر کد من برای این مساله را مشاهده می کنید:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 501; int dp[N]; int n, m; bool mat[N][N]; int main() { dp[0] = 0; dp[1] = 1; for( int i = 2; i < N; i ++ ) { dp[i] = 0; for( int j = 0; j < i-1; j ++ ) { int t = min(dp[j] + dp[i-j-1], dp[j+1] + dp[i-j-2]); dp[i] = max(dp[i], t); } } while( scanf("%d %d", &n, &m) == 2 ) { memset(mat, 0, sizeof mat); for( int i = 0; i < m; i ++ ) { int a, b; scanf("%d %d", &a, &b); mat[a][b] = mat[b][a] = true; } int cnt = 1, result = 0; for( int i = 1; i < n; i ++ ) if( mat[i-1][i] ) cnt ++; else { result += dp[cnt]; cnt = 1; } result += dp[cnt]; printf("%d\n", result); } return 0; }
لینک سوال: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3162
نوع سوال: شمارش - برنامه سازی پویا
توضیح راه حل : برای حل این مساله، به ازای تمامی مقادیر ممکن طول عدد، n، و مکانی از عدد که می خواهیم حتما برابر با 1 باشد، idx، مقدار مناسب را به پاسخ اضافه می کنیم:
for( n = 1; n < N; n ++ ) for( idx = 0; idx < n; idx ++ ) { memset( mat, -1, sizeof mat ); result += solve( N-1, eq, eq ) * 1. / n; }
که در این صورت پاسخ نهایی برابر خواهد بود با
:
cout << result / (b - a + 1) << endl;
تابع
تابعی است که با استفاده از برنامه سازی پویا و بصورت بازگشتی تعداد حالت های مقدار دهی بیت های 0 الی i را با فرض اینکه نتیجه مقایسه بیت های بزرگتر از i با a و b به ترتیب برابر با c1 و c2 است را بر می گرداند. c1 و c2 می توانند یکی از سه مقدار زیر باشند:
enum { eq = 0, le = 1, gr = 2 };
که eq به معنای مساوی، le به معنای کوچکتر، و gr به معنی بزرگتر است.
در این صورت تابع solve را می توان به صورت زیر پیاده سازی کرد:
int solve( int s, int c1, int c2 ) { if( c1 == le || c2 == gr ) return 0; if( s == -1 ) { return 1; } int& result = mat[s][c1][c2]; if( result == -1 ) { result = 0; if( s != idx && s != n - 1 ) result += solve( s - 1, update(sa, s, c1, 0), update(sb, s, c2, 0) ); if( s < n ) result += solve( s - 1, update(sa, s, c1, 1), update(sb, s, c2, 1) ); } return result; }
که sa نمایش دودوئی a و sb نمایش دودوئی b است، تابع
نتیجه مقایسه ی جدید در صورتیکه عددی که می خواهیم با آن مقایسه کنیم دارای نمایش دودوئی s باشد و نتیجه ی مقایسه تا قبل برابر با pre_c باشد و بخواهیم بیت i را برابر با bit قرار دهیم را بر می گرداند:
int update( string& s, int idx, int pre_c, int bit ) { if( pre_c != eq ) return pre_c; if( bit > s[idx] - '0' ) return gr; else if( bit < s[idx] - '0' ) return le; else return eq; }
لینک سوال: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3163
نوع سوال: حریصانه
توضیح راه حل : فرض کنید هرم را طوری دوران دهیم که اولین سیبی که شروع به گندیدن می کند در راس هرم قرار گیرد. همانطور که می توان به آسانی مشاهده کرد، صرف نظر از مقادیر x و y، با توجه به اینکه x همواره مثبت است، در روز i ام سیب های سطح i ام شروع به گندیدن کرده اند و پس از n روز تمام سیب ها شروع به گندیدن کرده اند. بنابراین جواب مساله حداکثر برابر است با n - 1. با توجه به اینکه پایین ترین سطح دارای
سیب است، و این مقدار برای مقادیر مثبت n همواره بزرگتر از n - 1 است، و اینکه این سیب ها دیرتر از بقیه سیب ها شروع به گندیدن می کنند و می توانیم سیب ها را همواره از این بخش انتخاب کنیم (توجه کنید که هرم را دوران داده ایم و این بخش در واقع یکی از وجه های بیرونی هرم است)، پس جواب n - 1 امکان پذیر است و جواب مساله برابر با n - 1 است:
#include <iostream> using namespace std; int n, x, y; int main() { while( cin >> n >> x >> y ) cout << n - 1 << endl; return 0; }
لینک سوال: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3164
نوع سوال: برنامه سازی پویا
توضیح راه حل : فرض کنید
نشانگر بیشترین مقدار لذت با i دلار باشد. در ابتدای کار
برابر با 0 است و بقیه مقادیر این آرایه برابر با ثابت خاصی به اسم invalid هستند:
const int invalid = 0x7fffffff;
حال، هر کدام از کالا ها را یک به یک بررسی می کنیم و این آرایه را به هنگام می کنیم. ابتدا به بررسی چگونگی به هنگام سازی این آرایه برای کالاهایی که عضو هیچ گروهی نیستند می پردازیم. برای یک کالا سه حالت داریم:
برابر با 0 باشد، یعنی برای تعداد استفاده از این کالا محدودیتی نداشته باشیم. در این صورت، مانند نسخه ای از مساله ی کوله پشتی که در آن محدودیتی برای تعداد استفاده از کالا نداریم، جدول را به صورت زیر به هنگام می کنیم:
void add_inf( vector<int>& v, int price, int value ) { for( int i = 0; i + price < v.size(); i ++ ) if( v[i] != invalid ) if( v[i + price] == invalid || v[i + price] < v[i] + value ) v[i + price] = v[i] + value; }
برابر با 1 باشد، یعنی حداکثر یکبار بتوانیم از این کالا استفاده کنیم، باز مانند معادل مساله کوله پشتی، جدول را بصورت زیر به هنگام می کنیم:
void add_one( vector<int>& v, int price, int value ) { for( int i = (int)v.size() - 1 - price; i >= 0; i -- ) if( v[i] != invalid ) if( v[i + price] == invalid || v[i + price] < v[i] + value ) v[i + price] = v[i] + value; }
بیشتر از 1 باشد. با یک مثال این حالت را شرح می دهم. فرض کنید
برابر با 9 باشد، در این صورت اگر ابتدا کالایی با هزینه
و ارزش
با استفاده از تابع add_one ای که در بالا دید، اضافه کنیم، و سپس کالایی با هزینه
و ارزش
، اگر دقت کنید متوجه خواهید شد که با این دو اضافه کردن تمام حالت های استفاده از این کالا به تعداد حداکثر 3 را در نظر گرفته ایم. اگر کالای دیگری را با هزینه
و ارزش
را بااستفاده از add_one اضافه کنیم، در این صورت تمام حالت های استفاده به تعداد حداکثر 7 را در نظر گرفته ایم. حال، اگر دوباره کالایی با هزینه
و ارزش
اضافه کنیم، در این صورت تمام حالت های استفاده به تعداد حداکثر 9 را در نظر گرفته ایم و به مطلوبمان رسیده ایم. در حالت کلی اگر
را به صورت حاصل جمع
تجزیه کنیم به طوری که داشته باشیم
، در این صورت اگر کالاهایی را به ترتیب با هزینه های
و ارزش های
را به ازای j از 1 تا p اضافه کنیم، به هدفمان می رسیم. بنابراین در این حالت به صورت کد زیر عمل می کنیم:
void add_k( vector<int>& v, int price, int value, int k ) { for( int i = 1; i <= k; i *= 2 ) { add_one( v, price * i, value * i ); k -= i; } if( k > 0 ) add_one( v, price * k, value * k ); }
و بالاخره، تابع زیر را برای تصمیم گیری استفاده از تابع های بالا می نویسیم:
void add( vector<int>& v, int idx ) { if( k[idx] == 0 ) add_inf( v, p[idx], e[idx] ); else add_k( v, p[idx], e[idx], k[idx] ); }
حال، به بررسی گروه ها می پردازیم. فرض کنید قبل از بررسی گروهی خاص، نتیجه در result قرار داشته باشد. فرض کنید اعضای این گروه برابر با
باشند. فرض کنید
آرایه حاصل از اعمال عنصر
بر روی result، بدون اعمال سایر عناصر، باشد. نتیجه اعمال این گروه در واقع ادغام
هاست. به این صورت که برای
، بهترین نتیجه را از بین
ها انتخاب می کنیم. برای این کار از تابع merge استفاده می کنیم که دو آرایه ی va و vb را ادغام می کند و نتیجه را در va قرار می دهد:
void merge( vector<int>& va, vector<int>& vb ) { for( int i = 0; i < va.size(); i ++ ) if( vb[i] != invalid ) if( va[i] == invalid || va[i] < vb[i] ) va[i] = vb[i]; }
و بالاخره بدنه اصلی برنامه من برای این سوال:
int main() { while( cin >> n >> d ) { for( int i = 0; i < n; i ++ ) cin >> k[i] >> e[i] >> p[i]; cin >> g; vector<int> result(d+1, invalid); result[0] = 0; string s; getline( cin, s ); memset(marked, 0, sizeof marked); for( int i = 0; i < g; i ++ ) { getline( cin, s ); istringstream hin( s ); vector<int> tresult = result; while( hin >> a ) { vector<int> v = tresult; add(v, a-1); merge(result, v); marked[a-1] = true; } } for( int i = 0; i < n; i ++ ) if( !marked[i] ) add( result, i ); if( result[d] != invalid && result[d] >= 0 ) cout << result[d] << endl; else cout << "i'm sorry..." << endl; } return 0; }
لینک سوال: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3165
نوع سوال: نظریه گراف
توضیح راه حل : این مساله، مساله مشهور بزرگترین مجموعه ی مستقل برای گراف های دوبخشی است که می توان آن را به صورت مساله جریان بیشینه مدل کرد.
يک مجموعه مستقل، مجموعه ای از رئوس است که بین هیچ دوتایی از آن ها یالی وجود نداشته باشد. بزرگترین مجموعه ی مستقل مجموعه ای است که در آن مجموع وزن رئوس انتخاب شده بیشنه باشد. (همانند این مساله)
یک پوشش راسی، مجموعه ای از رئوس است بصورتیکه به ازای هر یال حداقل یکی از انتها های آن در این مجموعه قرار داشته باشد. پوشش راسی کمینه، یک پوشش راسی است که مجموع وزن رئوس آن کمترین مقدار ممکن باشد.
می توان اثبات کرد که مکمل پوشش راسی کمینه، برابر با مجموعه مستقل بیشینه است. بنابراین اگر بتوانیم پوشش راسی کمینه را پیدا کنیم، توانسته ایم مجموعه مستقل بیشینه را نیز پیدا کنیم.
از آنجا که روش پیدا کردن پوشش راسی کمینه را در توضیح مساله paratroopers شرح داده ام، در اینجا به توضیح آن نمی پردازم، و تنها به کد این سوال بسنده می کنم:
#include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; const int N = 202; const int inf = 0x7fffffff; int cap[N][N], flow[N][N]; int adj[N][N], adjc[N]; int par[N], q[N], qc; int m, n, a, b, s; int boy( int x ) { return x; } int girl( int x ) { return m + x; } int src( ) { return m + n; } int trg( ) { return m + n + 1; } void add( int a, int b ) { adj[a][adjc[a]++] = b; adj[b][adjc[b]++] = a; } int maxflow( int n, int s, int t ) { int result = 0; memset( flow, 0, sizeof flow ); while( true ) { memset( par, -1, sizeof par ); qc = 1; par[s] = -2, q[0] = s; for( int i = 0; i < qc; i ++ ) { int u = q[i]; for( int j = 0; j < adjc[u]; j ++ ) { int v = adj[u][j]; if( cap[u][v] > flow[u][v] && par[v] == -1 ) { q[qc++] = v; par[v] = u; } } } if( par[t] == -1 ) break; int add = inf; int u = t; while( u != s ) { int v = par[u]; add = min( add, cap[v][u] - flow[v][u] ); u = v; } result += add; u = t; while( u != s ) { int v = par[u]; flow[v][u] += add; flow[u][v] -= add; u = v; } } return result; } int solve( vector<int>& vb, vector<int>& vg ) { maxflow( m + n + 2, src(), trg() ); int result = 0; for( int i = 0; i < m; i ++ ) if( par[boy(i)] != -1 ) { vb.push_back( i + 1 ); result += cap[src()][boy(i)]; } for( int i = 0; i < n; i ++ ) if( par[girl(i)] == -1 ) { vg.push_back( i + 1 ); result += cap[girl(i)][trg()]; } return result; } int main() { bool f = true; while( scanf("%d %d %d", &m, &n, &s) == 3 ) { if( !f ) printf("\n"); f = false; memset( adjc, 0, sizeof adjc ); memset( cap, 0, sizeof cap ); for( int i = 0; i < m; i ++ ) { scanf( "%d", &cap[src()][boy(i)] ); adj[src()][i] = boy(i); add( src(), i ); } for( int i = 0; i < n; i ++ ) { scanf( "%d", &cap[girl(i)][trg()] ); add( girl(i), trg() ); } for( int i = 0; i < s; i ++ ) { scanf( "%d %d", &a, &b ); cap[boy(a-1)][girl(b-1)] = inf; add( boy(a-1), girl(b-1) ); } std::vector<int> vboy, vgirl; int max_love = solve( vboy, vgirl ); printf( "%d %d %d\n", max_love, vboy.size(), vgirl.size() ); for( int i = 0; i < vboy.size(); i ++ ) { if( i ) printf(" "); printf("%d", vboy[i]); } printf("\n"); for( int i = 0; i < vgirl.size(); i ++ ) { if( i ) printf(" "); printf("%d", vgirl[i]); } printf("\n"); } return 0; }
لینک سوال: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3166
نوع سوال: نظریه گراف
توضیح راه حل : این سوال تقریبا آسان ترین سوال این مجموعه سوال است. برای حل آن ابتدا گراف را تشکیل می دهیم، و سپس با استفاده از الگوریتم Floyd-Warshall کوتاهترین مسیر را بین هر دو جفت راس پیدا می کنیم، که در این صورت کوتاهترین مسیر بین راس i و راس i برابر با طول کوتاهترین دوری است که راس i جزوی از آن است.
نوشتن کد این سوال نیز آسان است:
#include <cstdio> #include <cstring> int mat[101][101], n, m, a, b, c, d, hotels[100]; int main() { while( scanf("%d %d", &n, &c) == 2 ) { for( int i = 0; i < c; i ++ ) scanf("%d", &hotels[i]); scanf("%d", &m); memset( mat, 0, sizeof mat ); for( int i = 0; i < m; i ++ ) { scanf("%d %d %d", &a, &b, &d); if( mat[a][b] == 0 || mat[a][b] > d ) mat[a][b] = d; } for( int k = 1; k <= n; k ++ ) for( int i = 1; i <= n; i ++ ) for( int j = 1; j <= n; j ++ ) if( mat[i][k] && mat[k][j] ) if( mat[i][j] == 0 || mat[i][j] > mat[i][k] + mat[k][j] ) mat[i][j] = mat[i][k] + mat[k][j]; int result = -1; for( int i = 0; i < c; i ++ ) { int dist = mat[hotels[i]][hotels[i]]; if( dist != 0 ) if( result == -1 || dist < mat[hotels[result]][hotels[result]] ) result = i; } if( result == -1 ) printf("I will nerver go to that city!\n"); else printf("%d\n", hotels[result]); } return 0; }