poj 1087

二分圖匹配+floyd求圖中節點是否可達。模型很容易想到。此題我認爲用網絡流最好解釋,若是有device有重複的話。二分圖建模比較麻煩。一開始沒想到這點,用二分圖作的,可是AC了,數據應該沒有device重複的狀況。而後就是判斷一個插頭經過適配器能轉化成什麼其餘的插頭,剛開始用矩陣乘法來判斷這個關係,數據一開到500運行時就運行錯誤(感受也不是很大啊,至今還不知道緣由),後來在網上發現有用floyd作,想了想,確實能夠,並且還簡單,就是個DP的過程。ios

 1     #include <iostream>
 2     #include <cstdio>
 3     #include <cstring>
 4     #include <cmath>
 5     #include <map>
 6     #include <string>
 7     using namespace std;
 8     const int maxn=500+10;
 9     int n,m,k,tot;
10     map<string,int> a1;
11     map<string,int> a2;
12     int bi[maxn][maxn];
13     int x[maxn],y[maxn],ch[maxn],mark[maxn];
14     int g[maxn][maxn];
15     int dfs(int u)
16     {
17         int v;
18         for(v=1;v<=n;v++)
19         {
20             if(bi[u][v]&&!ch[v])
21             {
22                 ch[v]=1;
23                 if(!y[v]||dfs(y[v]))
24                 {
25                     y[v]=u;x[u]=v;
26                     return 1;
27                 }
28                 //ch[v]=0; ch[v]不用置爲0,從v沒有增廣路,之後無論那條只要走到v確定尚未增廣路,因此直接把他標記,省的之後再來搞她
29             }
30         }
31         return 0;
32     }
33     int MaxMatch()
34     {
35         memset(x,0,sizeof(x));
36         memset(y,0,sizeof(y));
37         int i,sum=0;
38         for(i=1;i<=m;i++)
39         {
40             memset(ch,0,sizeof(ch));
41             if(dfs(i)) sum++;
42         }
43         return sum;
44     }
45     void floyd()
46     {
47         int i,j,k;
48         for(k=1;k<=tot;k++)
49         {
50             for(i=1;i<=tot;i++)
51             {
52                 for(j=1;j<=tot;j++)
53                     g[i][j]=g[i][j]||(g[i][k]&&g[k][j]);
54             }
55         }
56     }
57     int main()
58     {
59         scanf("%d",&n);
60         int i;
61         string s1,s2;
62         tot=0;
63         for(i=0;i<n;i++)
64         {
65             cin>>s1;
66             a1[s1]=++tot;
67         }
68         scanf("%d",&m);
69         int u,v;
70         for(i=1;i<=m;i++)
71         {
72             cin>>s1>>s2;
73             if(!a1[s2]) a1[s2]=++tot;
74             v=a1[s2];
75             mark[i]=v;
76         }
77         scanf("%d",&k);
78         for(i=0;i<k;i++)
79         {
80             cin>>s1>>s2;
81             if(!a1[s1]) a1[s1]=++tot; if(!a1[s2]) a1[s2]=++tot;
82             u=a1[s1]; v=a1[s2];
83             g[u][v]=1;
84         }
85         for(i=1;i<=tot;i++) g[i][i]=1;
86         floyd();
87         for(i=1;i<=m;i++)
88         {
89             u=mark[i];
90             for(v=1;v<=n;v++)
91             {
92                 if(g[u][v]) bi[i][v]=1;
93             }
94         }
95         printf("%d\n",m-MaxMatch());
96         return 0;
97     }
相關文章
相關標籤/搜索