zoukankan      html  css  js  c++  java
  • 2011大连网络赛

    HDU 4001 To Miss Our Children Time

    题意:给你n个blocks。有3种,d[i] == 0:只能放在小于等于它的长和宽的积木上; d[i] == 1:只能放在长和宽小于等于它且面积小于他的木块上; d[i] == 2:只能放在长和宽偶小于它的木块上。求积木的最高高度。

    做法:记忆化搜索。因为d[i] = 0有可能存在环,就用map来记录长和宽一样的积木,然后把h[i]加在第一次出现的那个积木上,同时标记一下。注意细节,a[i] * b[i]会爆int,同时答案也要用longlong,输入的a[i] 有可能比 b[i]小,要换过来(被这个条件坑shi了)

     1 #include<iostream>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cstdio>
     5 #include<string>
     6 #include<queue>
     7 #include<cmath>
     8 #include<map>
     9 
    10 using namespace std;
    11 
    12 #define mnx 1050
    13 #define LL long long
    14 #define inf 0x3f3f3f3f
    15 #define MP make_pair
    16 #define lson l, m, rt << 1
    17 #define rson m+1, r, rt << 1 | 1
    18 #define mod 9973
    19 
    20 int a[mnx], b[mnx], d[mnx], n;
    21 LL dp[mnx], h[mnx];
    22 map< pair<int,int>, int > mp;
    23 bool vis[mnx];
    24 LL f( int k ){
    25     if( dp[k] > 0 ) return dp[k];
    26     dp[k] = h[k];
    27     LL tmp = dp[k];
    28     for( int i = 1; i <= n; ++i ){
    29         if( i == k || vis[i] ) continue ;
    30         if( d[k] == 0 ){
    31             if( a[k] >= a[i] && b[k] >= b[i] )
    32                 dp[k] = max( dp[k], tmp + f(i) );
    33         }
    34         else if( d[k] == 1 ){
    35             if( a[k] >= a[i] && b[k] >= b[i] && (LL)a[k] * b[k] > (LL)a[i] * b[i] )
    36                 dp[k] = max( dp[k], tmp + f(i) );
    37         }
    38         else{
    39             if( a[k] > a[i] && b[k] > b[i] )
    40                 dp[k] = max( dp[k], tmp + f(i) );
    41         }
    42     }
    43     return dp[k];
    44 }
    45 int main(){
    46     while( scanf( "%d", &n ) != EOF && n ){
    47         mp.clear();
    48         memset( vis, 0, sizeof(vis) );
    49         memset( dp, -1, sizeof(dp) );
    50         for( int i = 1; i <= n; ++i ){
    51             scanf( "%d%d%d%d", &a[i], &b[i], &h[i], &d[i] );
    52             if( a[i] < b[i] )
    53                 swap( a[i], b[i] );
    54             if( d[i] == 0 ){
    55                 if( mp.count( MP(a[i], b[i]) ) ){
    56                     int j = mp[MP(a[i],b[i])];
    57                     h[j] += h[i];
    58                     vis[i] = 1;
    59                     continue;
    60                 }
    61                 mp[MP(a[i],b[i])] = i;
    62             }
    63         }
    64         LL ans = 0;
    65         for( int i = 1; i <= n; ++i ){
    66             if( dp[i] < 0 )
    67                 ans = max( ans, f(i) );
    68         }
    69         printf( "%I64d
    ", ans );
    70     }
    71     return 0;
    72 }
    View Code

    HDU 4002 Find the maximum

    题意:φ(n)是欧拉函数,给你一个N,叫你求 2 ~ N中,n/φ(n)最大的n。

    做法:φ(n) = n * (1 - 1/p1) * (1 - 1/p2) * (1 - 1/p3) * … * (1 - 1/pt)

    则f(n) = n/φ(n) = 1 / [ (1 - 1/p1) * (1 - 1/p2) * (1 - 1/p3) * … * (1 - 1/pt) ]

    要使f(x)最大,须使x含尽量多的不同素数因子。用java先打表求出质因子的乘积。然后贴到c++。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <vector>
      5 #include <cmath>
      6 #include <queue>
      7 #include <iomanip>
      8 #include <map>
      9 #include <set>
     10 #include <algorithm>
     11 using namespace std;
     12 
     13 #define mxn 1020
     14 #define N 55
     15 #define mxe 20020
     16 #define MP make_pair
     17 #define PB push_back
     18 #define LL long long
     19 #define ULL unsigned LL
     20 #define inf 0x3f3f3f3f
     21 #define ls (i << 1)
     22 #define rs (ls | 1)
     23 #define md ((ll + rr) >> 1)
     24 
     25 char s[][mxn] = {
     26 "2",
     27 "6",
     28 "30",
     29 "210",
     30 "2310",
     31 "30030",
     32 "510510",
     33 "9699690",
     34 "223092870",
     35 "6469693230",
     36 "200560490130",
     37 "7420738134810",
     38 "304250263527210",
     39 "13082761331670030",
     40 "614889782588491410",
     41 "32589158477190044730",
     42 "1922760350154212639070",
     43 "117288381359406970983270",
     44 "7858321551080267055879090",
     45 "557940830126698960967415390",
     46 "40729680599249024150621323470",
     47 "3217644767340672907899084554130",
     48 "267064515689275851355624017992790",
     49 "23768741896345550770650537601358310",
     50 "2305567963945518424753102147331756070",
     51 "232862364358497360900063316880507363070",
     52 "23984823528925228172706521638692258396210",
     53 "2566376117594999414479597815340071648394470",
     54 "279734996817854936178276161872067809674997230",
     55 "31610054640417607788145206291543662493274686990",
     56 "4014476939333036189094441199026045136645885247730",
     57 "525896479052627740771371797072411912900610967452630",
     58 "72047817630210000485677936198920432067383702541010310",
     59 "10014646650599190067509233131649940057366334653200433090",
     60 "1492182350939279320058875736615841068547583863326864530410",
     61 "225319534991831177328890236228992001350685163362356544091910",
     62 "35375166993717494840635767087951744212057570647889977422429870",
     63 "5766152219975951659023630035336134306565384015606066319856068810",
     64 "962947420735983927056946215901134429196419130606213075415963491270",
     65 "166589903787325219380851695350896256250980509594874862046961683989710",
     66 "29819592777931214269172453467810429868925511217482600306406141434158090",
     67 "5397346292805549782720214077673687806275517530364350655459511599582614290",
     68 "1030893141925860008499560888835674370998623848299590975192766715520279329390",
     69 "198962376391690981640415251545285153602734402721821058212203976095413910572270",
     70 "39195588149163123383161804554421175259738677336198748467804183290796540382737190",
     71 "7799922041683461553249199106329813876687996789903550945093032474868511536164700810",
     72 "1645783550795210387735581011435590727981167322669649249414629852197255934130751870910",
     73 "367009731827331916465034565550136732339800312955331782619462457039988073311157667212930",
     74 "83311209124804345037562846379881038241134671040860314654617977748077292641632790457335110",
     75 "19078266889580195013601891820992757757219839668357012055907516904309700014933909014729740190",
     76 "4445236185272185438169240794291312557432222642727183809026451438704160103479600800432029464270",
     77 "1062411448280052319722448549835623701226301211611796930357321893850294264731624591303255041960530",
     78 "256041159035492609053110100510385311995538591998443060216114576417920917800321526504084465112487730",
     79 "64266330917908644872330635228106713310880186591609208114244758680898150367880703152525200743234420230",
     80 "16516447045902521732188973253623425320896207954043566485360902980990824644545340710198976591011245999110",
     81 "4343825573072363215565699965702960859395702691913457985649917484000586881515424606782330843435957697765930",
     82 "1168489079156465704987173290774096471177444024124720198139827803196157871127649219224446996884272620699035170",
     83 "316660540451402206051523961799780143689087330537799173695893334666158783075592938409825136155637880209438531070",
     84 "87714969705038411076272137418539099801877190558970371113762453702525982911939243939521562715111692818014473106390",
     85 "24647906487115793512432470614609487044327490547070674282967249490409801198254927547005559122946385681862066942895590",
     86 "6975357535853769564018389183934484833544679824821000822079731605785973739106144495802573231793827147966964944839451970",
     87 "2043779758005154482257388030892804056228591188672553240869361360495290305558100337270153956915591354354320728837959427210",
     88 "627440385707582426053018125484090845262177494922473844946893937672054123806336803541937264773086545786776463753253544153470",
     89 "195133959955058134502488637025552252876537200920889365778484014616008832503770745901542489344429915739687480227261852231729170",
     90 "61076929465933196099278943388997855150356143888238371488665496574810764573680243467182799164806563626522181311132959748531230210",
     91 "19361386640700823163471425054312320082662897612571563761906962414215012369856637179096947335243680669607531475629148240284399976570",
     92 "6408618978071972467109041692977377947361419109761187605191204559105169094422546906281089567965658301640092918433248067534136392244670",
     93 "2159704595610254721415747050533376368260798239989520222949435936418441984820398307416727184404426847652711313512004598759003964186453790",
     94 "749417494676758388331264226535081599786496989276363517363454269937199368732678212673604332988336116135490825788665595769374375572699465130",
     95 "261546705642188677527611215060743478325487449257450867559845540208082579687704696223087912212929304531286298200244292923511657074872113330370",
     96 "92325987091692603167246758916442447848897069587880156248625475693453150629759757766750033011164044499544063264686235401999614947429856005620610",
     97 "33145029365917644537041586451002838777754047982048976093256545773949681076083753038263261851007891975336318712022358509317861766127318306017798990",
     98 "12164225777291775545094262227518041831435735609411974226225152299039532954922737365042617099319896354948428967312205572919655268168725818308532229330",
     99 "4537256214929832278320159810864229603125529382310666386381981807541745792186181037160896178046321340395764004807452678699031415026934730229082521540090",
    100 "1719620105458406433483340568317543019584575635895742560438771105058321655238562613083979651479555788009994557822024565226932906295208262756822275663694110",
    101 "658614500390569664024119437665618976500892468548069400648049333237337193956369480811164206516669866807827915645835408481915303111064764635862931579194844130",
    102 "256201040651931599305382461251925781858847170265198996852091190629324168449027728035542876334984578188245059186229973899465052910204193443350680384306794366570",
    103 "101711813138816844924236837117014535397962326595284001750280202679841694874264008030110521904988877540733288496933299638087626005351064797010220112569797363528290",
    104 "40786437068665554814618971683922828694582892964708884701862361274616519644579867220074319283900539893834048687270253154873138028145776983601098265140488742774844290",
    105 "16681652761084211919179159418724436936084403222565933843061705761318156534633165693010396587115320816578125913093533540343113453511622786292849190442459895794911314610",
    106 "6989612506894284794136067796445539076219364950255126280242854713992307588011296425371356170001319422146234757586190553403764537021369947456703810795390696338067840821590",
    107 "2942626865402493898331284542303571951088352644057408163982241834590761494552755795081340947570555476723564832943786222982984870085996747879272304344859483158326560985889390",
    108 "1268272178988474870180783637732839510919079989588742918676346230708618204152237747680057948402909410467856442998771862105666479007064598335966363172634437241238747784918327090",
    109 "549161853502009618788279315138319508227961635491925683786857917896831682397918944745465091658459774732581839818468216291753585410058971079473435253750711325456377790869635629970",
    110 "241082053687382222648054619345722264112075157980955375182430625956709108572686416743259175238063841107603427680307546952079823995015888303888838076396562271875349850191770041556830",
    111 "106799349783510324633088196370154963001649294985563231205816767298822135097700082617263814630462281610668318462376243299771362029792038518622755267843677086440779983634954128409675690",
    112 "47952908052796135760256600170199578387740533448517890811411728517171138658867337095151452769077564443190074989606933241597341551376625294861617115261811011811910212652094403655944384810",
    113 "21914478980127834042437266277781207323197423785972676100815159932347210367102373052484213915468446950537864270250368491409985088979117759751759021674647632398042967182007142470766583858170",
    114 "10102574809838931493563579754057136575994012365333403682475788728812063979234193977195222615030954044197955428585419874540003126019373287245560908992012558535497807870905292679023395158616370",
    115 "4677492136955425281519937426128454234685227725149365904986290181439985622385431811441388070759331722463653363435049401912021447346969831994694700863301814601935485044229150510387831958439379310",
    116 "2184388827958183606469810778001988127598001347644753877628597514732473285653996655943128229044607914390526120724168070692914015911034911541522425303161947419103871515655013288351117524591190137770",
    117 "1046322248591969947499039362662952313119442645521837107384098209556854703828264398196758421712367190993062011826876505861905813621385722628389241720214572813750754455998751365120185294279180075991830",
    118 "509558935064289364432032169616857776489168568369134671296055828054188240764364761921821351373922822013621199759688858354748131233614846920025560717744496960296617420071391914813530238313960697008021210",
    119 "250193437116566077936127795281877168256181767069245123606363411574606426215303098103614283524596105608688009082007229452181332435704889837732550312412548007505639153255053430173443347012154702230938414110",
    120 "124846525121166472890127769845656706959834701767553316679575342375728606681436245953703527478773456698735316531921607496638484885416740029028542605893861455745313937474271661656548230159065196413238268640890",
    121 "62797802135946735863734268232365323600796854989079318289826397214991489160762431714712874321823048719463864215556568570809157897364620234601356930764612312239892910549558645813243759770009793795858849126367670",
    122 "31964081287196888554640742530273949712805599189441373009521636182430667982828077742788853029807931798207106885718293402541861369758591699412090677759187666930105491469725350718941073722934985042092154205321144030",
    123 "16653286350629578936967826858272727800371717177698955337960772451046378019053428503992992428529932466865902687459230862724309773644226275393699243112536774470584961055726907724568299409649127206930012340972316039630",
    124 "8709668761379269784034173446876636639594408083936553641753483991897255703964943107588335040121154680170867105541177741204814011615930342030904704147856733048115934632145172739949220591246493529224396454328521288726490",
    125 "4711930799906184953162487834760260422020574773409675520188634839616415335845034221205289256705544681972439104097777157991804380284218315038719444943990492579030720635990538452312528339864352999310398481791730017201031090",
    126 };
    127 char t[mxn];
    128 
    129 bool check(int k) {
    130     if(strlen(s[k]) < strlen(t)) return 1;
    131     if(strlen(s[k]) > strlen(t)) return 0;
    132     for(int i = 0; t[i]; ++i) {
    133         if(s[k][i] < t[i]) return 1;
    134         if(s[k][i] > t[i]) return 0;
    135     }
    136     return 1;
    137 }
    138 int main() {
    139     int cas;
    140     scanf("%d", &cas);
    141     while(cas--) {
    142         scanf("%s", t);
    143         for(int i = 0;; ++i) {
    144             if(!check(i)) {
    145                 printf("%s
    ", s[i-1]);
    146                 break;
    147             }
    148         }
    149     }
    150     return 0;
    151 }
    View Code

    HDU 4003 Find Metal Mineral

    题意:一棵树,K个机器人遍历所有结点所需的最少权值和。

    做法:前几天刚刚做过。dp+背包。dp[i][j]表示当前以i为根的子树,用j个机器人遍历所需要的最少权值和。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cstdio>
     5 #include<string>
     6 #include<queue>
     7 #include<cmath>
     8 #include<vector>
     9 
    10 using namespace std;
    11 
    12 #define mnx 20050
    13 #define ll long long
    14 #define inf 0x3f3f3f3f
    15 #define lson l, m, rt << 1
    16 #define rson m+1, r, rt << 1 | 1
    17 #define mod 9973
    18 
    19 int fst[mnx], nxt[mnx], vv[mnx], cost[mnx], e;
    20 void add( int u, int v, int c ){
    21     vv[e] = v, nxt[e] = fst[u], cost[e] = c, fst[u] = e++;
    22 }
    23 int k, dp[mnx][12];
    24 void dfs( int u, int fa ){
    25     for( int i = fst[u]; i != -1; i = nxt[i] ){
    26         int v = vv[i], c = cost[i];
    27         if( v == fa ) continue;
    28         dfs( v, u );
    29         for( int j = k; j >= 0; --j ){
    30             dp[u][j] += dp[v][0] + 2 * c;
    31             for( int jj = 1; jj <= j; ++jj ){
    32                 dp[u][j] = min( dp[u][j], dp[u][j-jj] + dp[v][jj] + jj * c );
    33             }
    34         }
    35     }
    36 }
    37 int main(){
    38     int n, s;
    39     while( scanf( "%d%d%d", &n, &s, &k ) != EOF ){
    40         memset( dp, 0, sizeof(dp) );
    41         memset( fst, -1, sizeof(fst) );
    42         e = 0;
    43         for( int i = 1; i < n; ++i ){
    44             int u, v, c;
    45             scanf( "%d%d%d", &u, &v, &c );
    46             add( u, v, c );
    47             add( v, u, c );
    48         }
    49         dfs( s, -1 );
    50         printf( "%d
    ", dp[s][k] );
    51     }
    52     return 0;
    53 }
    View Code

    HDU 4004 The Frog's Games

    题意:长为L的河,有n个石头,青蛙最多能跳m次,求能过河的最小的跳跃长度。

    做法:二分,注意细节就好。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cstdio>
     5 #include<string>
     6 #include<queue>
     7 #include<cmath>
     8 #include<vector>
     9 
    10 using namespace std;
    11 
    12 #define mnx 500500
    13 #define ll long long
    14 #define inf 0x3f3f3f3f
    15 #define lson l, m, rt << 1
    16 #define rson m+1, r, rt << 1 | 1
    17 #define mod 9973
    18 
    19 int a[mnx], n, m, L;
    20 bool check( int s ){
    21     int i = 0, j = 0, cur = 0;
    22     for( i = 0; i < m && cur < L; ++i ){
    23         cur += s;
    24         while( a[j] <= cur  && j <= n ){
    25             j++;
    26         }
    27         cur = a[j-1];
    28     }
    29     if( cur == L )
    30         return 1;
    31     else return 0;
    32 }
    33 int main(){
    34     while( scanf( "%d%d%d", &L, &n, &m ) != EOF ){
    35         for( int i = 0; i < n; ++i ){
    36             scanf( "%d", &a[i] );
    37         }
    38         a[n] = L;
    39         sort( a, a + n + 1 );
    40         int l = 0, r = L;
    41         while( l < r ){
    42             int mid = ( l + r ) >> 1;
    43             if( check( mid) )
    44                 r = mid;
    45             else l = mid + 1;
    46         }
    47         printf( "%d
    ", l );
    48     }
    49     return 0;
    50 }
    View Code

     HDU 4006 The kth great number

    题意:有两个操作,一个插入,一个询问第k大的数。

    做法:离线,hash,线段树。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cstdio>
     5 #include<string>
     6 #include<queue>
     7 #include<cmath>
     8 #include<map>
     9 
    10 using namespace std;
    11 
    12 #define mnx 1000050
    13 #define LL long long
    14 #define inf 0x3f3f3f3f
    15 #define MP make_pair
    16 #define lson l, m, rt << 1
    17 #define rson m+1, r, rt << 1 | 1
    18 #define mod 9973
    19 
    20 int n, k, a[mnx], b[mnx], g[mnx], sum[mnx<<2];
    21 void pushup( int rt ){
    22     sum[rt] = sum[rt<<1] + sum[rt<<1|1];
    23 }
    24 void update( int v, int l, int r, int rt ){
    25     if( l == r ){
    26         sum[rt]++;
    27         return ;
    28     }
    29     int m = ( l + r ) >> 1;
    30     if( v <= m ) update( v, lson );
    31     else update( v, rson );
    32     pushup( rt );
    33 }
    34 int query( int v, int l, int r, int rt ){
    35     if( l == r ){
    36         return l;
    37     }
    38     int m = ( l + r ) >> 1;
    39     if( sum[rt<<1] >= v ) return query( v, lson );
    40     else return query( v - sum[rt<<1], rson );
    41 }
    42 int main(){
    43     while( scanf( "%d%d", &n, &k ) != EOF ){
    44         memset( sum, 0, sizeof(sum) );
    45         int all = 0, v, cnt = 0;
    46         char s[3];
    47         for( int i = 0; i < n; ++i ){
    48             scanf( "%s", s );
    49             if( s[0] == 'I' ){
    50                 b[i] = 0;
    51                 scanf( "%d", &a[i] );
    52                 g[cnt++] = a[i];
    53             }
    54             else b[i] = 1;
    55         }
    56         sort( g, g + cnt );
    57         cnt = unique( g, g + cnt ) - g;
    58         for( int i = 0; i < n; ++i ){
    59             if( b[i] ){
    60                 v = query( all - k + 1, 1, cnt, 1 );
    61                 printf( "%d
    ", g[v-1]);
    62             }
    63             else{
    64                 v = lower_bound( g, g + cnt, a[i] ) - g + 1;
    65                 update( v, 1, cnt, 1 );
    66                 all++;
    67             }
    68         }
    69     }
    70     return 0;
    71 }
    View Code

     HDU 4007 Dave

    题意:已知 n 个人的坐标,求边长为R的正方形最多可以包含多少人。正方形的边与坐标轴是平行的。

    做法:离散化+扫描线+线段树。以每个人的坐标为左下角建正方形,求正方形的覆盖次数最多。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cstdio>
     5 #include<string>
     6 #include<queue>
     7 #include<cmath>
     8 #include<map>
     9 
    10 using namespace std;
    11 
    12 #define mnx 5050
    13 #define LL long long
    14 #define inf 0x3f3f3f3f
    15 #define MP make_pair
    16 #define lson l, m, rt << 1
    17 #define rson m+1, r, rt << 1 | 1
    18 #define mod 9973
    19 
    20 struct edge{
    21     int l, r, h, s;
    22     edge( int l = 0, int r = 0, int h = 0, int s = 0 ) : l(l), r(r), h(h), s(s) {}
    23     bool operator < ( const edge &b ) const {
    24         if( h == b.h )
    25             return s > b.s;
    26         return h < b.h;
    27     }
    28 }e[mnx];
    29 int sum[mnx<<2], vis[mnx<<2], X[mnx];
    30 void pushup( int rt ){
    31     if( vis[rt] ){
    32         sum[rt] = vis[rt] + max( sum[rt<<1|1], sum[rt<<1] );
    33     }
    34     else sum[rt] = max( sum[rt<<1], sum[rt<<1|1] );
    35 }
    36 void update( int L, int R, int v, int l, int r, int rt ){
    37     if( L <= l && R >= r ){
    38         vis[rt] += v;
    39         pushup( rt );
    40         return ;
    41     }
    42     int m = ( l + r ) >> 1;
    43     if( L <= m ) update( L, R, v, lson );
    44     if( R > m ) update( L, R, v, rson );
    45     pushup( rt );
    46 }
    47 int main(){
    48     int n, R, m;
    49     while( scanf( "%d%d", &n, &R ) != EOF ){
    50         memset( sum, 0, sizeof(sum) );
    51         memset( vis, 0, sizeof(vis) );
    52         int x, y;
    53         m = 0;
    54         for( int i = 1; i <= n; ++i ){
    55             scanf( "%d%d", &x, &y );
    56             X[m] = x, e[m++] = edge( x, x + R, y, 1 );
    57             X[m] = x + R, e[m++] = edge( x, x + R, y + R, -1 );
    58         }
    59         sort( X, X + m );
    60         int cnt = unique( X, X + m ) - X;
    61         sort( e, e + m );
    62         int ans = 0;
    63         for( int i = 0; i < m-1; ++i ){
    64             int L = lower_bound( X, X + cnt, e[i].l ) - X;
    65             int R = lower_bound( X, X + cnt, e[i].r ) - X;
    66             if( L <= R )
    67                 update( L, R, e[i].s, 0, cnt-1, 1 );
    68             ans = max( ans, sum[1] );
    69         }
    70         printf( "%d
    ", ans );
    71     }
    72     return 0;
    73 }
    View Code

     HDU 4008 Parent and son

    题意:给你一棵树,有m个询问,输入x,y,求出以x为根,y的儿子结点中最小的 和 y的子孙结点中最小的值。

    做法:树形dp。以1为根dfs,dp[i][0][0],表示 i 结点所在的子树,儿子结点最小的。dp[i][1][0],表示 i 结点所在的子树,子孙结点最小的。f[i]表示除了 i 结点和 i 结点 所在的子树,其他所有结点最小的。dfs1处理处dp数组,dfs2处理出f数组。对于询问,分3种情况。x == y,x和y在不同的子树 或者 x与y的lca是x, x与y的lca是y。

      1 #include<iostream>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<cstdio>
      5 #include<string>
      6 #include<queue>
      7 #include<cmath>
      8 #include<map>
      9 
     10 using namespace std;
     11 
     12 #define mnx 200050
     13 #define LL long long
     14 #define inf 0x3f3f3f3f
     15 #define MP make_pair
     16 #define lson l, m, rt << 1
     17 #define rson m+1, r, rt << 1 | 1
     18 #define mod 9973
     19 
     20 int fst[mnx], nxt[mnx], vv[mnx], e;
     21 void init(){
     22     memset( fst, -1, sizeof(fst) );
     23     e = 0;
     24 }
     25 void add( int u, int v ){
     26     vv[e] = v, nxt[e] = fst[u], fst[u] = e++;
     27 }
     28 int dp[mnx][2][3], dep[mnx], fa[22][mnx], f[mnx];
     29 void update( int k, int d, int val ){
     30     dp[k][d][2] = val;
     31     sort( dp[k][d], dp[k][d]+3 );
     32 }
     33 void dfs1( int d, int u, int p ){
     34     dep[u] = d;
     35     fa[0][u] = p;
     36     for( int i = fst[u]; i != -1; i = nxt[i] ){
     37         int v = vv[i];
     38         if( v == p ) continue;
     39         dfs1( d+1, v, u );
     40         update( u, 0, v );
     41         update( u, 1, min(v, dp[v][1][0]) );
     42     }
     43 }
     44 int n, m;
     45 void lcaInit(){
     46     for( int k = 0; k < 21; ++k ){
     47         for( int i = 1; i <= n; ++i ){
     48             if( fa[k][i] == -1 )
     49                 fa[k+1][i] = -1;
     50             else
     51                 fa[k+1][i] = fa[k][fa[k][i]];
     52         }
     53     }
     54 }
     55 void dfs2( int u ){
     56     for( int i = fst[u]; i != -1; i = nxt[i] ){
     57         int v = vv[i];
     58         if( v == fa[0][u] ) continue;
     59         f[v] = f[u];
     60         if( fa[0][u] != -1 )
     61             f[v] = min( f[v], fa[0][u] );
     62         int x = min( v, dp[v][1][0] );
     63         if( x == dp[u][1][0] )
     64             f[v] = min( f[v], dp[u][1][1] );
     65         else
     66             f[v] = min( f[v], dp[u][1][0] );
     67         dfs2( v );
     68     }
     69 }
     70 int lca( int u, int v ){
     71     if( dep[u] > dep[v] ) swap( u, v );
     72     for( int k = 0; k < 22; ++k )
     73         if( (dep[v] - dep[u] ) >> k & 1 )
     74             v = fa[k][v];
     75     if( u == v ) return v;
     76     for( int k = 21; k >= 0; --k ){
     77         if( fa[k][u] != fa[k][v] )
     78             u = fa[k][u], v = fa[k][v];
     79     }
     80     return fa[0][u];
     81 }
     82 int kfa( int u, int k ){
     83     for( int i = 0; i < 22; ++i ){
     84         if( k >> i & 1 )
     85             u = fa[i][u];
     86     }
     87     return u;
     88 }
     89 int main(){
     90     int cas;
     91     scanf( "%d", &cas );
     92     while( cas-- ){
     93         scanf( "%d%d", &n, &m );
     94         init();
     95         for( int i = 1; i < n; ++i ){
     96             int u, v;
     97             scanf( "%d%d", &u, &v );
     98             add( u, v ), add( v, u );
     99         }
    100         memset( dp, 0x3f, sizeof(dp) );
    101         dfs1( 0, 1, -1 );
    102         lcaInit();
    103         memset( f, 0x3f, sizeof(f) );
    104         dfs2( 1 );
    105         while( m-- ){
    106             int x, y;
    107             scanf( "%d%d", &x, &y );
    108             int p = lca( x, y );
    109             int ans1 = inf, ans2 = inf;
    110             if( x == y ){
    111                 ans1 = dp[x][0][0];
    112                 if( x == 1 )
    113                     ans2 = 2;
    114                 else
    115                     ans2 = 1;
    116                 if( fa[0][x] != -1 )
    117                     ans1 = min( ans1, fa[0][x] );
    118             }
    119             else if( p == x || ( p != x && p != y ) ){
    120                 ans1 = dp[y][0][0];
    121                 ans2 = dp[y][1][0];
    122             }
    123             else{
    124                 int w = kfa( x, dep[x] - dep[y] - 1 );
    125                 ans2 = f[w];
    126                 if( w == dp[y][0][0] ) ans1 = dp[y][0][1];
    127                 else ans1 = dp[y][0][0];
    128                 if( fa[0][y] != -1 ) ans1 = min( ans1, fa[0][y] );
    129             }
    130             if( ans1 == inf || ans2 == inf )
    131                 puts( "no answers!" );
    132             else printf( "%d %d
    ", ans1, ans2 );
    133         }
    134         puts( "" );
    135     }
    136     return 0;
    137 }
    View Code

     HDU 4009 Transfer water

    题意:有n个房子,最开始的时候都没有水,坐标为( a, b, c ),建一个水井,需要 x * c 的花费;如果u 与 v之间能够建水渠,如果u的c大于等于v的c,那么需要花费 dis(u, v) * y,否则需要花费dis(u, v) * y + z;问你要使这n个房子有水,最少需要花费多少。

    做法:最小树形图。虚拟一个源点,源点到所有房子的花费是 x * c,然后按照题意连边,做最小树形图就好了。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cstdio>
     5 #include<string>
     6 #include<queue>
     7 #include<cmath>
     8 #include<map>
     9 
    10 using namespace std;
    11 
    12 #define mnx 1050
    13 #define LL long long
    14 #define inf 0x3f3f3f3f
    15 #define MP make_pair
    16 #define lson l, m, rt << 1
    17 #define rson m+1, r, rt << 1 | 1
    18 #define mod 9973
    19 
    20 struct point{
    21     int x, y, c;
    22     point( int x = 0, int y = 0, int c = 0 ) : x(x), y(y), c(c) {}
    23     void input(){
    24         scanf( "%d%d%d", &x, &y, &c );
    25     }
    26 };
    27 int dis( point a, point b ){
    28     return abs( a.x - b.x ) + abs( a.y - b.y ) + abs( a.c - b.c );
    29 }
    30 struct edge{
    31     int u, v, w;
    32     edge( int u = 0, int v = 0, int w = 0 ) : u(u), v(v), w(w) {}
    33 };
    34 int in[mnx], id[mnx], v[mnx], pre[mnx];
    35 edge e[mnx*mnx];
    36 void zhu_liu( int root, int n, int m ){
    37     int s, t, idx = n, ans = 0;
    38     while( idx ){
    39         for( int i = 1; i <= n; ++i )
    40             in[i] = inf, id[i] = v[i] = -1;
    41         for( int i = 1; i <= m; ++i ){
    42             s = e[i].u, t =e[i].v;
    43             if( e[i].w > in[t] || s == t ) continue;
    44             pre[t] = s;
    45             in[t] = e[i].w;
    46         }
    47         in[root] = 0, pre[root] = root;
    48         for( int i = 1; i <= n; ++i )
    49             ans += in[i];
    50         idx = 0;
    51         for( int i = 1; i <= n; ++i ){
    52             if( v[i] == -1 ){
    53                 t = i;
    54                 while( v[t] == -1 )
    55                     v[t] = i, t = pre[t];
    56                 if( v[t] != i || t == root ) continue;
    57                 id[t] = ++idx;
    58                 for( s = pre[t]; s != t; s = pre[s] )
    59                     id[s] = idx;
    60             }
    61         }
    62         if( idx == 0 ) continue;
    63         for( int i = 1; i <= n; ++i )
    64             if( id[i] == -1 ) id[i] = ++idx;
    65         for( int i = 1; i <= m; ++i ){
    66             e[i].w -= in[e[i].v];
    67             e[i].u = id[e[i].u];
    68             e[i].v = id[e[i].v];
    69         }
    70         n = idx;
    71         root = id[root];
    72     }
    73     printf( "%d
    ", ans );
    74 }
    75 point p[mnx];
    76 int main(){
    77     int n, x, y, z;
    78     while( scanf( "%d%d%d%d", &n, &x, &y, &z ) != EOF ){
    79         if( n == 0 && x == 0 && y == 0 && z == 0 ) break;
    80         int m = 0;
    81         for( int i = 1; i <= n; ++i ){
    82             p[i].input();
    83             e[++m] = edge( n+1, i, p[i].c * x );
    84         }
    85         int g, k;
    86         for( int i = 1; i <= n; ++i ){
    87             scanf( "%d", &k );
    88             while( k-- ){
    89                 scanf( "%d", &g );
    90                 if( p[i].c >= p[g].c )
    91                     e[++m] = edge( i, g, dis( p[i], p[g] ) * y );
    92                 else e[++m] = edge( i, g, dis( p[i], p[g] ) * y + z );
    93             }
    94         }
    95         zhu_liu( n+1, n+1, m );
    96     }
    97     return 0;
    98 }
    View Code
  • 相关阅读:
    面向对象编程思想(一)
    IT第十九天
    IT第十八天
    关于面试,来自无锡一位尊者的建议
    IT第十一天、第十二天、第十三天
    数据结构 3动态规划
    java 零碎1
    数据结构 2.迭代与递归
    数据结构 1.算法分析
    java 字符串(正则表达式)未完
  • 原文地址:https://www.cnblogs.com/LJ-blog/p/4396676.html
Copyright © 2011-2022 走看看