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
  • 相关阅读:
    POJ 3140 Contestants Division (树dp)
    POJ 3107 Godfather (树重心)
    POJ 1655 Balancing Act (树的重心)
    HDU 3534 Tree (经典树形dp)
    HDU 1561 The more, The Better (树形dp)
    HDU 1011 Starship Troopers (树dp)
    Light oj 1085
    Light oj 1013
    Light oj 1134
    FZU 2224 An exciting GCD problem(GCD种类预处理+树状数组维护)同hdu5869
  • 原文地址:https://www.cnblogs.com/LJ-blog/p/4396676.html
Copyright © 2011-2022 走看看