HDU 4975 (杭電多校 #10 1005題)A simple Gaussian elimination problem.(網絡流之最大流)

題目地址:HDU 4975

對這題簡直無語。。。本來以爲這題要用什麼更先進的方法,結果還是老方法,這麼卡時間真的好嗎。。。。比賽的時候用了判環的方法,一直TLE。。後來換了矩陣DP的方式,加了加剪枝就過了。。無語了。。

代碼如下:

  1. #include <cstdio> 
  2. #include <cstring> 
  3. #include <algorithm> 
  4. #include <iostream> 
  5. #include <cstdio> 
  6. #include <string> 
  7. #include <cstring> 
  8. #include <stdlib.h> 
  9. #include <math.h> 
  10. #include <ctype.h> 
  11. #include <queue> 
  12. #include <map> 
  13. #include <set> 
  14. #include <algorithm> 
  15.  
  16. using namespace std; 
  17. const int INF=0x3f3f3f3f; 
  18. int head[1010], source, sink, nv, cnt, vis[610][600], mp[600][600]; 
  19. int cur[1010], num[1010], d[1010], pre[1010]; 
  20. int a[600], b[600]; 
  21. struct node 
  22.     int u, v, cap, next; 
  23. } edge[1000000]; 
  24. void add(int u, int v, int cap) 
  25.     edge[cnt].v=v; 
  26.     edge[cnt].cap=cap; 
  27.     edge[cnt].next=head[u]; 
  28.     head[u]=cnt++; 
  29.  
  30.     edge[cnt].v=u; 
  31.     edge[cnt].cap=0; 
  32.     edge[cnt].next=head[v]; 
  33.     head[v]=cnt++; 
  34. void bfs() 
  35.     memset(num,0,sizeof(num)); 
  36.     memset(d,-1,sizeof(d)); 
  37.     queue<int>q; 
  38.     q.push(sink); 
  39.     d[sink]=0; 
  40.     num[0]=1; 
  41.     while(!q.empty()) 
  42.     { 
  43.         int u=q.front(); 
  44.         q.pop(); 
  45.         for(int i=head[u]; i!=-1; i=edge[i].next) 
  46.         { 
  47.             int v=edge[i].v; 
  48.             if(d[v]==-1) 
  49.             { 
  50.                 d[v]=d[u]+1; 
  51.                 num[d[v]]++; 
  52.                 q.push(v); 
  53.             } 
  54.         } 
  55.     } 
  56. int isap() 
  57.     memcpy(cur,head,sizeof(cur)); 
  58.     int flow=0, u=pre[source]=source, i; 
  59.     bfs(); 
  60.     while(d[source]<nv) 
  61.     { 
  62.         if(u==sink) 
  63.         { 
  64.             int f=INF, pos; 
  65.             for(i=source; i!=sink; i=edge[cur[i]].v) 
  66.             { 
  67.                 if(f>edge[cur[i]].cap) 
  68.                 { 
  69.                     f=edge[cur[i]].cap; 
  70.                     pos=i; 
  71.                 } 
  72.             } 
  73.             for(i=source; i!=sink; i=edge[cur[i]].v) 
  74.             { 
  75.                 edge[cur[i]].cap-=f; 
  76.                 edge[cur[i]^1].cap+=f; 
  77.             } 
  78.             flow+=f; 
  79.             u=pos; 
  80.         } 
  81.         for(i=cur[u]; i!=-1; i=edge[i].next) 
  82.         { 
  83.             if(d[edge[i].v]+1==d[u]&&edge[i].cap) 
  84.                 break
  85.         } 
  86.         if(i!=-1) 
  87.         { 
  88.             cur[u]=i; 
  89.             pre[edge[i].v]=u; 
  90.             u=edge[i].v; 
  91.         } 
  92.         else 
  93.         { 
  94.             if(--num[d[u]]==0) break
  95.             int mind=nv; 
  96.             for(i=head[u]; i!=-1; i=edge[i].next) 
  97.             { 
  98.                 if(mind>d[edge[i].v]&&edge[i].cap) 
  99.                 { 
  100.                     mind=d[edge[i].v]; 
  101.                     cur[u]=i; 
  102.                 } 
  103.             } 
  104.             d[u]=mind+1; 
  105.             num[d[u]]++; 
  106.             u=pre[u]; 
  107.         } 
  108.     } 
  109.     return flow; 
  110. bool panduan(int n,int m) 
  111.     memset(vis,0,sizeof(vis)); 
  112.     int i, j, k; 
  113.     for(i=1;i<=n;i++) 
  114.     { 
  115.         if(a[i]==0||a[i]==9*m) continue
  116.         for(j=1;j<=m;j++) 
  117.         { 
  118.             if(b[j]==0||b[j]==9*n) continue
  119.             for(k=j+1;k<=m;k++) 
  120.             { 
  121.                 int t1=0, t2=0; 
  122.                 if(mp[i][j]&&mp[i][k]!=9) 
  123.                 { 
  124.                     if(vis[j][k]) return 1; 
  125.                     t1=1; 
  126.                 } 
  127.                 if(mp[i][k]&&mp[i][j]!=9) 
  128.                 { 
  129.                     if(vis[k][j]) return 1; 
  130.                     t2=1; 
  131.                 } 
  132.                 if(t1) vis[k][j]=1; 
  133.                 if(t2) vis[j][k]=1; 
  134.             } 
  135.         } 
  136.     } 
  137.     return 0; 
  138. int read() 
  139.     int x = 0; 
  140.     char ch = ' '
  141.     while(ch < '0' || ch > '9') ch = getchar(); 
  142.     while(ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); 
  143.     return x; 
  144. int main() 
  145.     int t, i, j, n, m, sum1, sum2, num=0; 
  146.     t=read(); 
  147.     while(t--) 
  148.     { 
  149.         num++; 
  150.         n=read(); 
  151.         m=read(); 
  152.         sum1=sum2=0; 
  153.         memset(head,-1,sizeof(head)); 
  154.         cnt=0; 
  155.         source=0; 
  156.         sink=n+m+1; 
  157.         nv=sink+1; 
  158.         for(i=1; i<=n; i++) 
  159.         { 
  160.             a[i]=read(); 
  161.             sum1+=a[i]; 
  162.         } 
  163.         for(i=1; i<=m; i++) 
  164.         { 
  165.             b[i]=read(); 
  166.             sum2+=b[i]; 
  167.         } 
  168.         printf("Case #%d: ",num); 
  169.         if(sum1!=sum2) 
  170.         { 
  171.             puts("So naive!"); 
  172.             continue
  173.         } 
  174.         for(i=1; i<=n; i++) 
  175.         { 
  176.             add(source,i,a[i]); 
  177.             for(j=1; j<=m; j++) 
  178.             { 
  179.                 add(i,j+n,9); 
  180.             } 
  181.         } 
  182.         for(i=1; i<=m; i++) 
  183.         { 
  184.             add(i+n,sink,b[i]); 
  185.         } 
  186.         int ans=isap(); 
  187.         if(ans!=sum1) 
  188.         { 
  189.             puts("So naive!"); 
  190.             continue
  191.         } 
  192.         for(i=1;i<=n;i++) 
  193.         { 
  194.             for(j=head[i];j!=-1;j=edge[j].next) 
  195.             { 
  196.                 int v=edge[j].v; 
  197.                 if(v>n&&v<=n+m) 
  198.                     mp[i][v-n]=9-edge[j].cap; 
  199.             } 
  200.         } 
  201.         if(panduan(n,m)) 
  202.         { 
  203.             puts("So young!"); 
  204.         } 
  205.         else 
  206.             puts("So simple!"); 
  207.     } 
  208.     return 0; 
  209. }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章